• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 29845725671

21 Jul 2026 03:48PM UTC coverage: 63.994% (+0.01%) from 63.981%
29845725671

push

github

web-flow
TRUNK-6713: Switch to saner DaemonThread protection scheme (#6360)

54 of 80 new or added lines in 6 files covered. (67.5%)

7 existing lines in 6 files now uncovered.

24227 of 37858 relevant lines covered (63.99%)

0.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.38
/api/src/main/java/org/openmrs/scheduler/jobrunr/JobRequestHandlerAdapter.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.scheduler.jobrunr;
11

12
import java.util.Map;
13

14
import org.jobrunr.JobRunrException;
15
import org.openmrs.api.context.Daemon;
16
import org.openmrs.scheduler.TaskContext;
17
import org.openmrs.scheduler.TaskData;
18
import org.openmrs.scheduler.TaskException;
19
import org.openmrs.scheduler.TaskHandler;
20
import org.springframework.context.ApplicationContext;
21
import org.springframework.context.ApplicationContextAware;
22
import org.springframework.core.GenericTypeResolver;
23
import org.springframework.stereotype.Component;
24

25
/**
26
 * A generic handler that delegates execution to the appropriate {@link TaskHandler}.
27
 * 
28
 * @since 2.9.0
29
 */
30
@Component
31
public class JobRequestHandlerAdapter implements org.jobrunr.jobs.lambdas.JobRequestHandler<JobRequestAdapter>, ApplicationContextAware {
1✔
32
        
33
        private ApplicationContext applicationContext;
34

35
        /**
36
         * The capability that proves to {@link Daemon} this class is allowed to act with daemon
37
     * permissions.
38
         */
39
        private static volatile Daemon.CallerKey daemonCallerKey;
40

41
        @Override
42
        public void setApplicationContext(ApplicationContext applicationContext) {
43
                this.applicationContext = applicationContext;
1✔
44
        }
1✔
45

46
        @SuppressWarnings("unchecked")
47
        @Override
48
        public void run(JobRequestAdapter jobRequestAdapter) throws Exception {
49
                TaskData request = jobRequestAdapter.getJobRequest();
1✔
50
                TaskContext context = new JobRunrTaskContext(jobContext(), jobRequestAdapter.getUserSystemId());
1✔
51
                Map<String, TaskHandler> handlers = applicationContext.getBeansOfType(TaskHandler.class);
1✔
52

53
                for (TaskHandler handler : handlers.values()) {
1✔
54
                        Class<?> genericType = GenericTypeResolver.resolveTypeArgument(handler.getClass(), TaskHandler.class);
1✔
55
                        if (genericType != null && genericType.isAssignableFrom(request.getClass())) {
1✔
56
                                Daemon.executeScheduledTaskAsUser(jobRequestAdapter.getUserSystemId(), () -> {
1✔
57
                                        try {
58
                                                handler.execute(request, context);
×
59
                                        } catch (TaskException e) {
×
60
                                                if (e.isDoNotRetry()) {
×
61
                                                        throw new JobRunrException(e.getMessage(), e.isDoNotRetry(), e);
×
62
                                                } else {
63
                                                        throw e;
×
64
                                                }
65
                                        }
×
66
                                }, daemonCallerKey());
1✔
67
                                return;
×
68
                        }
69
                }
1✔
70
                throw new IllegalStateException("No handler found for " + request.getClass().getName());
×
71
        }
72

73
        /**
74
         * Receives the {@link Daemon} caller key. Called only by {@link Daemon} during its initialization.
75
         *
76
         * @param callerKey the caller key issued by {@link Daemon}
77
         * @since 3.0.0, 2.9.0, 2.8.9
78
         */
79
        public static void setDaemonCallerKey(Daemon.CallerKey callerKey) {
80
                if (callerKey != null && daemonCallerKey == null) {
1✔
81
                        daemonCallerKey = callerKey;
1✔
82
                }
83
        }
1✔
84

85
        private static Daemon.CallerKey daemonCallerKey() {
86
                if (daemonCallerKey == null) {
1✔
87
                        // Guarantee Daemon has initialized and therefore handed us the key, regardless of the order in
88
                        // which the two classes were first loaded.
NEW
89
                        Daemon.ensureInitialized();
×
90
                }
91
                return daemonCallerKey;
1✔
92
        }
93
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc