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.provisioning.java.job;
20  
21  import org.apache.syncope.core.persistence.api.dao.JobStatusDAO;
22  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
23  import org.apache.syncope.core.persistence.api.entity.JobStatus;
24  import org.apache.syncope.core.provisioning.api.event.JobStatusEvent;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  import org.springframework.context.event.EventListener;
28  import org.springframework.scheduling.annotation.Async;
29  
30  public class JobStatusUpdater {
31  
32      protected static final Logger LOG = LoggerFactory.getLogger(JobStatusUpdater.class);
33  
34      protected final JobStatusDAO jobStatusDAO;
35  
36      protected final EntityFactory entityFactory;
37  
38      public JobStatusUpdater(final JobStatusDAO jobStatusDAO, final EntityFactory entityFactory) {
39          this.jobStatusDAO = jobStatusDAO;
40          this.entityFactory = entityFactory;
41      }
42  
43      /**
44       * It's important to note that responding to job status updates
45       * must be done in async mode, and via a separate special thread executor
46       * that attempts to synchronize job execution serially by only making one thread
47       * active at a given time. Not doing so will force the event executor to launch
48       * separate threads per each status update, which would result in multiple concurrent
49       * INSERT operations on the database, and failing.
50       *
51       * @param event the event
52       */
53      @Async("jobStatusUpdaterThreadExecutor")
54      @EventListener
55      public void update(final JobStatusEvent event) {
56          if (event.getJobStatus() == null) {
57              LOG.debug("Deleting status for job '{}'", event.getJobRefDesc());
58              jobStatusDAO.delete(event.getJobRefDesc());
59          } else {
60              LOG.debug("Updating job '{}' with status '{}'", event.getJobRefDesc(), event.getJobStatus());
61              JobStatus jobStatus = entityFactory.newEntity(JobStatus.class);
62              jobStatus.setKey(event.getJobRefDesc());
63              jobStatus.setStatus(event.getJobStatus());
64              jobStatusDAO.save(jobStatus);
65          }
66      }
67  }