Skip to content

Package: TriggerServiceImpl

TriggerServiceImpl

nameinstructionbranchcomplexitylinemethod
TriggerServiceImpl()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
adaptTrigger(Trigger)
M: 85 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 21 C: 0
0%
M: 1 C: 0
0%
adaptTriggerCreator(TriggerCreator)
M: 43 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
count(KapuaQuery)
M: 21 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
create(TriggerCreator)
M: 214 C: 0
0%
M: 24 C: 0
0%
M: 13 C: 0
0%
M: 40 C: 0
0%
M: 1 C: 0
0%
delete(KapuaId, KapuaId)
M: 34 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
find(KapuaId, KapuaId)
M: 30 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
getCronJobTriggerDefinition()
M: 8 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
getIntervalJobTriggerDefinition()
M: 8 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
getTriggerDefinition(String)
M: 15 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
lambda$adaptTrigger$6(Trigger, EntityManager)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$count$5(KapuaQuery, EntityManager)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$create$0(TriggerCreator, EntityManager)
M: 25 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
lambda$delete$2(KapuaId, KapuaId, EntityManager)
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
lambda$find$3(KapuaId, KapuaId, EntityManager)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$query$4(KapuaQuery, EntityManager)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$update$1(Trigger, EntityManager)
M: 29 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
query(KapuaQuery)
M: 37 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
update(Trigger)
M: 246 C: 0
0%
M: 26 C: 0
0%
M: 14 C: 0
0%
M: 44 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2017, 2022 Eurotech and/or its affiliates and others
3: *
4: * This program and the accompanying materials are made
5: * available under the terms of the Eclipse Public License 2.0
6: * which is available at https://www.eclipse.org/legal/epl-2.0/
7: *
8: * SPDX-License-Identifier: EPL-2.0
9: *
10: * Contributors:
11: * Eurotech - initial API and implementation
12: *******************************************************************************/
13: package org.eclipse.kapua.service.scheduler.trigger.quartz;
14:
15: import org.eclipse.kapua.KapuaDuplicateNameException;
16: import org.eclipse.kapua.KapuaEntityNotFoundException;
17: import org.eclipse.kapua.KapuaException;
18: import org.eclipse.kapua.commons.service.internal.AbstractKapuaService;
19: import org.eclipse.kapua.commons.util.ArgumentValidator;
20: import org.eclipse.kapua.locator.KapuaProvider;
21: import org.eclipse.kapua.model.domain.Actions;
22: import org.eclipse.kapua.model.id.KapuaId;
23: import org.eclipse.kapua.model.query.KapuaQuery;
24: import org.eclipse.kapua.model.query.predicate.AttributePredicate;
25: import org.eclipse.kapua.service.authorization.AuthorizationService;
26: import org.eclipse.kapua.service.authorization.permission.PermissionFactory;
27: import org.eclipse.kapua.service.scheduler.SchedulerDomains;
28: import org.eclipse.kapua.service.scheduler.exception.TriggerInvalidDatesException;
29: import org.eclipse.kapua.service.scheduler.exception.TriggerInvalidSchedulingException;
30: import org.eclipse.kapua.service.scheduler.quartz.SchedulerEntityManagerFactory;
31: import org.eclipse.kapua.service.scheduler.quartz.driver.QuartzTriggerDriver;
32: import org.eclipse.kapua.service.scheduler.quartz.driver.exception.TriggerNeverFiresException;
33: import org.eclipse.kapua.service.scheduler.trigger.Trigger;
34: import org.eclipse.kapua.service.scheduler.trigger.TriggerAttributes;
35: import org.eclipse.kapua.service.scheduler.trigger.TriggerCreator;
36: import org.eclipse.kapua.service.scheduler.trigger.TriggerListResult;
37: import org.eclipse.kapua.service.scheduler.trigger.TriggerQuery;
38: import org.eclipse.kapua.service.scheduler.trigger.TriggerService;
39: import org.eclipse.kapua.service.scheduler.trigger.definition.TriggerDefinition;
40: import org.eclipse.kapua.service.scheduler.trigger.definition.TriggerDefinitionFactory;
41: import org.eclipse.kapua.service.scheduler.trigger.definition.TriggerDefinitionService;
42: import org.eclipse.kapua.service.scheduler.trigger.definition.TriggerProperty;
43: import org.slf4j.Logger;
44: import org.slf4j.LoggerFactory;
45:
46: import javax.inject.Inject;
47: import javax.validation.constraints.NotNull;
48: import java.util.ArrayList;
49: import java.util.Date;
50: import java.util.List;
51:
52: /**
53: * {@link TriggerService} implementation.
54: *
55: * @since 1.0.0
56: */
57: @KapuaProvider
58: public class TriggerServiceImpl extends AbstractKapuaService implements TriggerService {
59:
60: private static final Logger LOG = LoggerFactory.getLogger(TriggerServiceImpl.class);
61:
62: @Inject
63: private AuthorizationService authorizationService;
64: @Inject
65: private PermissionFactory permissionFactory;
66:
67: @Inject
68: private TriggerDefinitionService triggerDefinitionService;
69: @Inject
70: private TriggerDefinitionFactory triggerDefinitionFactory;
71:
72: private static TriggerDefinition intervalJobTriggerDefinition;
73: private static TriggerDefinition cronJobTriggerDefinition;
74:
75: /**
76: * Constructor.
77: *
78: * @since 1.0.0
79: */
80: public TriggerServiceImpl() {
81: super(SchedulerEntityManagerFactory.getInstance(), null);
82: }
83:
84: @Override
85: public Trigger create(TriggerCreator triggerCreator) throws KapuaException {
86: //
87: // Argument validation
88: ArgumentValidator.notNull(triggerCreator, "triggerCreator");
89: ArgumentValidator.notNull(triggerCreator.getScopeId(), "triggerCreator.scopeId");
90: ArgumentValidator.validateEntityName(triggerCreator.getName(), "triggerCreator.name");
91: ArgumentValidator.notNull(triggerCreator.getStartsOn(), "triggerCreator.startsOn");
92:
93: //
94: // Check Access
95: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.write, triggerCreator.getScopeId()));
96:
97: //
98: // Convert creator to new model.
99: // To be removed after removing of TriggerCreator.cronScheduling and TriggerCreator.retryInterval
100: adaptTriggerCreator(triggerCreator);
101:
102: //
103: // Check trigger definition
104: TriggerDefinition triggerDefinition = triggerDefinitionService.find(triggerCreator.getTriggerDefinitionId());
105:• if (triggerDefinition == null) {
106: throw new KapuaEntityNotFoundException(TriggerDefinition.TYPE, triggerCreator.getTriggerDefinitionId());
107: }
108:
109:• for (TriggerProperty jsp : triggerCreator.getTriggerProperties()) {
110:• for (TriggerProperty jsdp : triggerDefinition.getTriggerProperties()) {
111:• if (jsp.getName().equals(jsdp.getName())) {
112: ArgumentValidator.areEqual(jsp.getPropertyType(), jsdp.getPropertyType(), "triggerCreator.triggerProperties{}." + jsp.getName() + ".propertyType");
113: ArgumentValidator.notNull(jsp.getPropertyValue(), "triggerCreator.triggerProperties{}." + jsp.getName() + ".propertyValue");
114: break;
115: }
116: }
117: }
118:
119: //
120: // Check duplicate name
121: TriggerQuery query = new TriggerQueryImpl(triggerCreator.getScopeId());
122: query.setPredicate(query.attributePredicate(TriggerAttributes.NAME, triggerCreator.getName()));
123:
124:• if (count(query) > 0) {
125: throw new KapuaDuplicateNameException(triggerCreator.getName());
126: }
127:
128:• if (triggerCreator.getEndsOn() != null) {
129: Date startTime = triggerCreator.getStartsOn();
130: Date endTime = triggerCreator.getEndsOn();
131:
132:• if (endTime.before(new Date()) ||
133:• startTime.getTime() == endTime.getTime() ||
134:• startTime.after(endTime)) {
135: throw new TriggerInvalidDatesException(startTime, endTime, new Date());
136: }
137: }
138:
139: //
140: // Do create
141: try {
142: return entityManagerSession.doTransactedAction(em -> {
143:
144: Trigger trigger = TriggerDAO.create(em, triggerCreator);
145:
146: // Quartz Job definition and creation
147:• if (getIntervalJobTriggerDefinition().getId().equals(triggerCreator.getTriggerDefinitionId())) {
148: QuartzTriggerDriver.createIntervalJobTrigger(trigger);
149:• } else if (getCronJobTriggerDefinition().getId().equals(triggerCreator.getTriggerDefinitionId())) {
150: QuartzTriggerDriver.createCronJobTrigger(trigger);
151: }
152: //else {
153: // Is a DeviceConnect trigger
154: //}
155:
156: return trigger;
157: });
158: } catch (TriggerNeverFiresException tnfe) {
159: TriggerProperty schedulingTriggerProperty = null;
160:• if (getIntervalJobTriggerDefinition().getId().equals(triggerCreator.getTriggerDefinitionId())) {
161: schedulingTriggerProperty = triggerCreator.getTriggerProperty("interval");
162:• } else if (getCronJobTriggerDefinition().getId().equals(triggerCreator.getTriggerDefinitionId())) {
163: schedulingTriggerProperty = triggerCreator.getTriggerProperty("cronExpression");
164: }
165:
166: throw new TriggerInvalidSchedulingException(
167: tnfe,
168: triggerCreator.getStartsOn(),
169: triggerCreator.getEndsOn(),
170:• triggerCreator.getTriggerDefinitionId(),
171: schedulingTriggerProperty != null ? schedulingTriggerProperty.getPropertyValue() : null);
172: }
173: }
174:
175: @Override
176: public Trigger update(Trigger trigger) throws KapuaException {
177: //
178: // Argument validation
179: ArgumentValidator.notNull(trigger.getScopeId(), "trigger.scopeId");
180: ArgumentValidator.notNull(trigger.getId(), "trigger.id");
181: ArgumentValidator.validateEntityName(trigger.getName(), "trigger.name");
182:
183: //
184: // Check Access
185: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.write, trigger.getScopeId()));
186:
187: //
188: // Check existence
189:• if (find(trigger.getScopeId(), trigger.getId()) == null) {
190: throw new KapuaEntityNotFoundException(trigger.getType(), trigger.getId());
191: }
192:
193: adaptTrigger(trigger);
194:
195: //
196: // Check trigger definition
197: TriggerDefinition triggerDefinition = triggerDefinitionService.find(trigger.getTriggerDefinitionId());
198:• if (triggerDefinition == null) {
199: throw new KapuaEntityNotFoundException(TriggerDefinition.TYPE, trigger.getTriggerDefinitionId());
200: }
201:
202:• for (TriggerProperty jsp : trigger.getTriggerProperties()) {
203:• for (TriggerProperty jsdp : triggerDefinition.getTriggerProperties()) {
204:• if (jsp.getName().equals(jsdp.getName())) {
205: ArgumentValidator.areEqual(jsp.getPropertyType(), jsdp.getPropertyType(), "trigger.triggerProperties[]." + jsp.getName());
206: ArgumentValidator.notNull(jsp.getPropertyType(), "trigger.triggerProperties{}." + jsp.getName());
207: break;
208: }
209: }
210: }
211:
212: //
213: // Check duplicate name
214: TriggerQuery query = new TriggerQueryImpl(trigger.getScopeId());
215: query.setPredicate(
216: query.andPredicate(
217: query.attributePredicate(TriggerAttributes.NAME, trigger.getName()),
218: query.attributePredicate(TriggerAttributes.ENTITY_ID, trigger.getId(), AttributePredicate.Operator.NOT_EQUAL)
219: )
220: );
221:
222:• if (count(query) > 0) {
223: throw new KapuaDuplicateNameException(trigger.getName());
224: }
225:
226:• if (trigger.getEndsOn() != null) {
227: Date startTime = new Date(trigger.getStartsOn().getTime());
228: Date endTime = new Date(trigger.getEndsOn().getTime());
229:
230:• if (endTime.before(new Date()) ||
231:• startTime.getTime() == (endTime.getTime()) ||
232:• startTime.after(endTime)) {
233: throw new TriggerInvalidDatesException(startTime, endTime, new Date());
234: }
235: }
236:
237: //
238: // Do update
239: try {
240: return entityManagerSession.doTransactedAction(em -> {
241: Trigger updatedTrigger = TriggerDAO.update(em, trigger);
242:
243: // Quartz Job definition and creation
244:• if (getIntervalJobTriggerDefinition().getId().equals(updatedTrigger.getTriggerDefinitionId())) {
245: QuartzTriggerDriver.deleteTrigger(updatedTrigger);
246: QuartzTriggerDriver.createIntervalJobTrigger(trigger);
247:• } else if (getCronJobTriggerDefinition().getId().equals(updatedTrigger.getTriggerDefinitionId())) {
248: QuartzTriggerDriver.deleteTrigger(updatedTrigger);
249: QuartzTriggerDriver.createCronJobTrigger(trigger);
250: }
251: //else {
252: // Is a DeviceConnect trigger
253: //}
254:
255: return updatedTrigger;
256: });
257: } catch (TriggerNeverFiresException tnfe) {
258: TriggerProperty schedulingTriggerProperty = null;
259:• if (getIntervalJobTriggerDefinition().getId().equals(trigger.getTriggerDefinitionId())) {
260: schedulingTriggerProperty = trigger.getTriggerProperty("interval");
261:• } else if (getCronJobTriggerDefinition().getId().equals(trigger.getTriggerDefinitionId())) {
262: schedulingTriggerProperty = trigger.getTriggerProperty("cronExpression");
263: }
264:
265: throw new TriggerInvalidSchedulingException(
266: tnfe,
267: trigger.getStartsOn(),
268: trigger.getEndsOn(),
269:• trigger.getTriggerDefinitionId(),
270: schedulingTriggerProperty != null ? schedulingTriggerProperty.getPropertyValue() : null
271: );
272: }
273: }
274:
275: @Override
276: public void delete(KapuaId scopeId, KapuaId triggerId) throws KapuaException {
277: //
278: // Argument validation
279: ArgumentValidator.notNull(triggerId, "scopeId");
280: ArgumentValidator.notNull(scopeId, "triggerId");
281:
282: //
283: // Check Access
284: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.delete, scopeId));
285:
286: //
287: // Check existence
288:• if (find(scopeId, triggerId) == null) {
289: throw new KapuaEntityNotFoundException(Trigger.TYPE, triggerId);
290: }
291:
292: //
293: // Do delete
294: entityManagerSession.doTransactedAction(em -> {
295: Trigger trigger = TriggerDAO.delete(em, scopeId, triggerId);
296:
297: QuartzTriggerDriver.deleteTrigger(trigger);
298:
299: return trigger;
300: });
301: }
302:
303: @Override
304: public Trigger find(KapuaId scopeId, KapuaId triggerId) throws KapuaException {
305: //
306: // Argument validation
307: ArgumentValidator.notNull(scopeId, "scopeId");
308: ArgumentValidator.notNull(triggerId, "triggerId");
309:
310: //
311: // Check Access
312: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.read, scopeId));
313:
314: //
315: // Do find
316: Trigger trigger = entityManagerSession.doAction(em -> TriggerDAO.find(em, scopeId, triggerId));
317:
318:• if (trigger != null) {
319: adaptTrigger(trigger);
320: }
321:
322: return trigger;
323: }
324:
325: @Override
326: public TriggerListResult query(KapuaQuery query) throws KapuaException {
327: //
328: // Argument validation
329: ArgumentValidator.notNull(query, "query");
330:
331: //
332: // Check Access
333: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.read, query.getScopeId()));
334:
335: //
336: // Do query
337: TriggerListResult triggers = entityManagerSession.doAction(em -> TriggerDAO.query(em, query));
338:
339:• for (Trigger trigger : triggers.getItems()) {
340: adaptTrigger(trigger);
341: }
342:
343: return triggers;
344: }
345:
346: @Override
347: public long count(KapuaQuery query) throws KapuaException {
348: //
349: // Argument validation
350: ArgumentValidator.notNull(query, "query");
351:
352: //
353: // Check Access
354: authorizationService.checkPermission(permissionFactory.newPermission(SchedulerDomains.SCHEDULER_DOMAIN, Actions.read, query.getScopeId()));
355:
356: //
357: // Do count
358: return entityManagerSession.doAction(em -> TriggerDAO.count(em, query));
359: }
360:
361: //
362: // Private methods
363: //
364:
365: /**
366: * Gets the {@link TriggerDefinition} named 'Interval Job'
367: *
368: * @return he {@link TriggerDefinition} named 'Interval Job'
369: * @throws KapuaException In case is not found.
370: * @since 1.1.0
371: */
372: private TriggerDefinition getIntervalJobTriggerDefinition() throws KapuaException {
373:• if (intervalJobTriggerDefinition == null) {
374: intervalJobTriggerDefinition = getTriggerDefinition("Interval Job");
375: }
376:
377: return intervalJobTriggerDefinition;
378: }
379:
380: /**
381: * Gets the {@link TriggerDefinition} named 'Cron Job'
382: *
383: * @return he {@link TriggerDefinition} named 'Cron Job'
384: * @throws KapuaException In case is not found.
385: * @since 1.1.0
386: */
387: private TriggerDefinition getCronJobTriggerDefinition() throws KapuaException {
388:• if (cronJobTriggerDefinition == null) {
389: cronJobTriggerDefinition = getTriggerDefinition("Cron Job");
390: }
391:
392: return cronJobTriggerDefinition;
393: }
394:
395: /**
396: * Gets the {@link TriggerDefinition} by the given name.
397: *
398: * @param triggerDefinitionName The {@link TriggerDefinition#getName()} to look for.
399: * @return The {@link TriggerDefinition} by the given name.
400: * @throws KapuaException In case nothing is found.
401: * @since 1.1.0
402: */
403: private synchronized TriggerDefinition getTriggerDefinition(String triggerDefinitionName) throws KapuaException {
404: TriggerDefinition triggerDefinition = triggerDefinitionService.findByName(triggerDefinitionName);
405:
406:• if (triggerDefinition == null) {
407: throw new KapuaEntityNotFoundException(TriggerDefinition.TYPE, triggerDefinitionName);
408: }
409:
410: return triggerDefinition;
411: }
412:
413: /**
414: * Adapts {@link TriggerCreator#getRetryInterval()} and {@link TriggerCreator#getCronScheduling()} to the new model
415: * which make use of {@link TriggerDefinition}s
416: *
417: * @param triggerCreator The {@link TriggerCreator} to adapt.
418: * @throws KapuaException In case that {@link TriggerDefinition} is not found.
419: * @since 1.1.0
420: */
421: private void adaptTriggerCreator(TriggerCreator triggerCreator) throws KapuaException {
422:• if (triggerCreator.getRetryInterval() != null) {
423: triggerCreator.setTriggerDefinitionId(getIntervalJobTriggerDefinition().getId());
424: triggerCreator.getTriggerProperties().add(triggerDefinitionFactory.newTriggerProperty("interval", Integer.class.getName(), triggerCreator.getRetryInterval().toString()));
425:• } else if (triggerCreator.getCronScheduling() != null) {
426: triggerCreator.setTriggerDefinitionId(getCronJobTriggerDefinition().getId());
427: triggerCreator.getTriggerProperties().add(triggerDefinitionFactory.newTriggerProperty("cronExpression", String.class.getName(), triggerCreator.getCronScheduling()));
428: }
429: }
430:
431: /**
432: * Adapts {@link Trigger#getRetryInterval()} and {@link Trigger#getCronScheduling()} to the new model
433: * which make use of {@link TriggerDefinition}s
434: *
435: * @param trigger The {@link Trigger} to adapt.
436: * @throws KapuaException In case that {@link TriggerDefinition} is not found.
437: * @since 1.1.0
438: */
439: private void adaptTrigger(@NotNull Trigger trigger) throws KapuaException {
440: boolean converted = false;
441:• if (trigger.getRetryInterval() != null) {
442: trigger.setTriggerDefinitionId(getIntervalJobTriggerDefinition().getId());
443:
444: List<TriggerProperty> triggerProperties = new ArrayList<>(trigger.getTriggerProperties());
445: triggerProperties.add(triggerDefinitionFactory.newTriggerProperty("interval", Integer.class.getName(), trigger.getRetryInterval().toString()));
446: trigger.setTriggerProperties(triggerProperties);
447:
448: trigger.setRetryInterval(null);
449:
450: converted = true;
451:
452:• } else if (trigger.getCronScheduling() != null) {
453: trigger.setTriggerDefinitionId(getCronJobTriggerDefinition().getId());
454:
455: List<TriggerProperty> triggerProperties = new ArrayList<>(trigger.getTriggerProperties());
456: triggerProperties.add(triggerDefinitionFactory.newTriggerProperty("cronExpression", String.class.getName(), trigger.getCronScheduling()));
457: trigger.setTriggerProperties(triggerProperties);
458:
459: trigger.setCronScheduling(null);
460:
461: converted = true;
462: }
463:
464:• if (converted) {
465: try {
466: entityManagerSession.doTransactedAction(em -> TriggerDAO.update(em, trigger));
467: } catch (Exception e) {
468: LOG.warn("Cannot convert Trigger to new format!", e);
469: }
470: }
471: }
472: }