Skip to content

Package: JobDeviceManagementOperationManagerServiceImpl

JobDeviceManagementOperationManagerServiceImpl

nameinstructionbranchcomplexitylinemethod
JobDeviceManagementOperationManagerServiceImpl()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
checkLastNotification(DeviceManagementOperation, NotifyStatus, String)
M: 42 C: 0
0%
M: 12 C: 0
0%
M: 7 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
getDeviceManagementOperation(KapuaId, KapuaId)
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%
getJobDeviceManagementOperation(KapuaId, KapuaId)
M: 35 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
processJobTargetOnNotification(KapuaId, KapuaId, Date, String, NotifyStatus)
M: 215 C: 0
0%
M: 17 C: 0
0%
M: 10 C: 0
0%
M: 49 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 46 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2019, 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.device.management.job.manager.internal;
14:
15: import org.eclipse.kapua.KapuaEntityNotFoundException;
16: import org.eclipse.kapua.KapuaException;
17: import org.eclipse.kapua.job.engine.JobEngineFactory;
18: import org.eclipse.kapua.job.engine.JobEngineService;
19: import org.eclipse.kapua.job.engine.JobStartOptions;
20: import org.eclipse.kapua.locator.KapuaLocator;
21: import org.eclipse.kapua.locator.KapuaProvider;
22: import org.eclipse.kapua.model.id.KapuaId;
23: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperation;
24: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperationAttributes;
25: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperationFactory;
26: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperationListResult;
27: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperationQuery;
28: import org.eclipse.kapua.service.device.management.job.JobDeviceManagementOperationService;
29: import org.eclipse.kapua.service.device.management.job.manager.JobDeviceManagementOperationManagerService;
30: import org.eclipse.kapua.service.device.management.message.notification.NotifyStatus;
31: import org.eclipse.kapua.service.device.management.registry.operation.DeviceManagementOperation;
32: import org.eclipse.kapua.service.device.management.registry.operation.DeviceManagementOperationFactory;
33: import org.eclipse.kapua.service.device.management.registry.operation.DeviceManagementOperationProperty;
34: import org.eclipse.kapua.service.device.management.registry.operation.DeviceManagementOperationRegistryService;
35: import org.eclipse.kapua.service.device.management.registry.operation.notification.ManagementOperationNotification;
36: import org.eclipse.kapua.service.job.targets.JobTarget;
37: import org.eclipse.kapua.service.job.targets.JobTargetAttributes;
38: import org.eclipse.kapua.service.job.targets.JobTargetFactory;
39: import org.eclipse.kapua.service.job.targets.JobTargetListResult;
40: import org.eclipse.kapua.service.job.targets.JobTargetQuery;
41: import org.eclipse.kapua.service.job.targets.JobTargetService;
42: import org.eclipse.kapua.service.job.targets.JobTargetStatus;
43: import org.slf4j.Logger;
44: import org.slf4j.LoggerFactory;
45:
46: import java.util.Date;
47:
48: /**
49: * {@link JobDeviceManagementOperationManagerService} implementation.
50: *
51: * @since 1.1.0
52: */
53: @KapuaProvider
54: public class JobDeviceManagementOperationManagerServiceImpl implements JobDeviceManagementOperationManagerService {
55:
56: private static final Logger LOG = LoggerFactory.getLogger(JobDeviceManagementOperationManagerService.class);
57:
58: private static final KapuaLocator LOCATOR = KapuaLocator.getInstance();
59:
60: private static final DeviceManagementOperationRegistryService DEVICE_MANAGEMENT_OPERATION_REGISTRY_SERVICE = LOCATOR.getService(DeviceManagementOperationRegistryService.class);
61: private static final DeviceManagementOperationFactory DEVICE_MANAGEMENT_OPERATION_FACTORY = LOCATOR.getFactory(DeviceManagementOperationFactory.class);
62:
63: private static final JobDeviceManagementOperationService JOB_DEVICE_MANAGEMENT_OPERATION_SERVICE = LOCATOR.getService(JobDeviceManagementOperationService.class);
64: private static final JobDeviceManagementOperationFactory JOB_DEVICE_MANAGEMENT_OPERATION_FACTORY = LOCATOR.getFactory(JobDeviceManagementOperationFactory.class);
65:
66: private static final JobEngineService JOB_ENGINE_SERVICE = LOCATOR.getService(JobEngineService.class);
67: private static final JobEngineFactory JOB_ENGINE_FACTORY = LOCATOR.getFactory(JobEngineFactory.class);
68:
69: private static final JobTargetService JOB_TARGET_SERVICE = LOCATOR.getService(JobTargetService.class);
70: private static final JobTargetFactory JOB_TARGET_FACTORY = LOCATOR.getFactory(JobTargetFactory.class);
71:
72: @Override
73: public void processJobTargetOnNotification(KapuaId scopeId, KapuaId operationId, Date updateOn, String resource, NotifyStatus status) throws KapuaException {
74:• if (NotifyStatus.RUNNING.equals(status)) {
75: return;
76: }
77:
78: DeviceManagementOperation deviceManagementOperation = getDeviceManagementOperation(scopeId, operationId);
79:
80: //
81: // UGLY 'DEPLOY-V2'-related part
82:• if (checkLastNotification(deviceManagementOperation, status, resource)) {
83: return;
84: }
85:
86: //
87: // Update the job target
88: JobDeviceManagementOperation jobDeviceManagementOperation;
89: try {
90: jobDeviceManagementOperation = getJobDeviceManagementOperation(scopeId, operationId);
91: } catch (KapuaEntityNotFoundException kenfe) {
92: LOG.warn("The operationId {} does not match any Job. Likely this is run interactively using a DeviceManagementService ", operationId);
93: return;
94: }
95:
96: JobTargetQuery jobTargetQuery = JOB_TARGET_FACTORY.newQuery(scopeId);
97: jobTargetQuery.setPredicate(
98: jobTargetQuery.andPredicate(
99: jobTargetQuery.attributePredicate(JobTargetAttributes.JOB_ID, jobDeviceManagementOperation.getJobId()),
100: jobTargetQuery.attributePredicate(JobTargetAttributes.JOB_TARGET_ID, deviceManagementOperation.getDeviceId())
101: )
102: );
103:
104: short attempts = 0;
105: short limit = 3;
106: boolean failed;
107: JobTarget jobTarget = null;
108: do {
109: try {
110: JobTargetListResult jobTargets = JOB_TARGET_SERVICE.query(jobTargetQuery);
111: jobTarget = jobTargets.getFirstItem();
112:
113:• if (jobTarget == null) {
114: LOG.warn("JobTarget with targetId {} for Job {} not found! This is something strange that happened and needs some checking! Reference JobDeviceManagementOperation: {}", deviceManagementOperation.getDeviceId(), jobDeviceManagementOperation.getJobId(), jobDeviceManagementOperation.getId());
115: return;
116: }
117:
118:• switch (status) {
119: case COMPLETED:
120: jobTarget.setStatus(JobTargetStatus.NOTIFIED_COMPLETION);
121: break;
122: case FAILED:
123: jobTarget.setStatus(JobTargetStatus.PROCESS_FAILED);
124: break;
125: case STALE:
126: default:
127: break;
128: }
129:
130: JOB_TARGET_SERVICE.update(jobTarget);
131: failed = false;
132: } catch (Exception e) {
133: failed = true;
134: attempts++;
135:
136:• if (jobTarget == null) {
137: throw e;
138: }
139:
140:• if (attempts >= limit) {
141: LOG.warn("Update JobTarget {} with status {}... FAILED! ({}/{}) Throwing error: {}...", jobTarget.getId(), jobTarget.getStatus(), attempts, limit, e.getMessage());
142: throw e;
143: } else {
144: LOG.warn("Update JobTarget {} with status {}... FAILED! ({}/{}) Retrying...", jobTarget.getId(), jobTarget.getStatus(), attempts, limit);
145: }
146: }
147:• } while (failed);
148:
149: //
150: // If PROCESS_FAILED no need to continue the JobTarget processing
151:• if (JobTargetStatus.PROCESS_FAILED.equals(jobTarget.getStatus())) {
152: return;
153: }
154:
155: //
156: // Start the job
157: JobStartOptions jobStartOptions = JOB_ENGINE_FACTORY.newJobStartOptions();
158: jobStartOptions.addTargetIdToSublist(jobTarget.getId());
159: jobStartOptions.setFromStepIndex(jobTarget.getStepIndex());
160: jobStartOptions.setEnqueue(true);
161:
162: JOB_ENGINE_SERVICE.startJob(scopeId, jobDeviceManagementOperation.getJobId(), jobStartOptions);
163: }
164:
165: /**
166: * This fixes the double {@link NotifyStatus#COMPLETED} {@link ManagementOperationNotification} set from Kura
167: * when performing a Device package download with the 'install' flag is set to {@code true}.
168: * <p>
169: * If this is not the last {@link ManagementOperationNotification} the processing must stop.
170: *
171: * @param deviceManagementOperation The current {@link DeviceManagementOperation} which the {@link ManagementOperationNotification} refers to.
172: * @param status The {@link ManagementOperationNotification} {@link NotifyStatus}.
173: * @param resource The {@link ManagementOperationNotification} resource.
174: * @return {@code true} if this is the last {@link ManagementOperationNotification} for the {@link DeviceManagementOperation}, {@code false} otherwise.
175: * @since 1.1.0
176: */
177: private boolean checkLastNotification(DeviceManagementOperation deviceManagementOperation, NotifyStatus status, String resource) {
178: boolean isLastNotification = true;
179:• if (!NotifyStatus.FAILED.equals(status)) {
180:• for (DeviceManagementOperationProperty ip : deviceManagementOperation.getInputProperties()) {
181:• if (ip.getName().equals("kapua.package.download.install")) {
182:• if (resource.equals("download")) {
183:• isLastNotification = !Boolean.parseBoolean(ip.getPropertyValue());
184: }
185: break;
186: }
187: }
188: }
189:
190:• if (!isLastNotification) {
191: return true;
192: }
193: return false;
194: }
195:
196: /**
197: * Gets the {@link JobDeviceManagementOperation} associated with the given {@link DeviceManagementOperation#getOperationId()}.
198: *
199: * @param scopeId The scope {@link KapuaId} of the {@link JobDeviceManagementOperation}.
200: * @param operationId The {@link DeviceManagementOperation#getOperationId()} to match.
201: * @return The matched {@link JobDeviceManagementOperation}
202: * @throws KapuaEntityNotFoundException if there is no {@link JobDeviceManagementOperation} with the given {@code operationId}.
203: * @throws KapuaException If something goes bad.
204: * @since 1.1.0
205: */
206: private JobDeviceManagementOperation getJobDeviceManagementOperation(KapuaId scopeId, KapuaId operationId) throws KapuaException {
207:
208: DeviceManagementOperation deviceManagementOperation = getDeviceManagementOperation(scopeId, operationId);
209:
210: JobDeviceManagementOperationQuery query = JOB_DEVICE_MANAGEMENT_OPERATION_FACTORY.newQuery(scopeId);
211: query.setPredicate(query.attributePredicate(JobDeviceManagementOperationAttributes.DEVICE_MANAGEMENT_OPERATION_ID, deviceManagementOperation.getId()));
212:
213: JobDeviceManagementOperationListResult operations = JOB_DEVICE_MANAGEMENT_OPERATION_SERVICE.query(query);
214: JobDeviceManagementOperation jobDeviceManagementOperation = operations.getFirstItem();
215:
216:• if (jobDeviceManagementOperation == null) {
217: throw new KapuaEntityNotFoundException(JobDeviceManagementOperation.TYPE, operationId);
218: }
219:
220: return jobDeviceManagementOperation;
221: }
222:
223:
224: /**
225: * Gets the {@link DeviceManagementOperation} that matches the given {@code operationId}.
226: *
227: * @param scopeId The scope {@link KapuaId} of the {@link DeviceManagementOperation}.
228: * @param operationId The {@link DeviceManagementOperation#getOperationId()} to match.
229: * @return The matched {@link DeviceManagementOperation}.
230: * @throws KapuaEntityNotFoundException if there is no {@link DeviceManagementOperation} with the given {@code operationId}.
231: * @throws KapuaException If something goes bad.
232: * @since 1.1.0
233: */
234: private DeviceManagementOperation getDeviceManagementOperation(KapuaId scopeId, KapuaId operationId) throws KapuaException {
235: DeviceManagementOperation deviceManagementOperation = DEVICE_MANAGEMENT_OPERATION_REGISTRY_SERVICE.findByOperationId(scopeId, operationId);
236:
237:• if (deviceManagementOperation == null) {
238: throw new KapuaEntityNotFoundException(DeviceManagementOperation.TYPE, operationId);
239: }
240:
241: return deviceManagementOperation;
242: }
243: }