RD: Additional checks before copying device to monitoring subsystem. Added the same checks before onboarding. Improved error and exception handling during request processing. GUI: Change the set status Admin button to ask about the new status.

This commit is contained in:
ipatini 2023-10-06 21:03:56 +03:00
parent 043e5cbe71
commit 243b6f4182
5 changed files with 67 additions and 33 deletions

View File

@ -43,6 +43,8 @@ public class DeviceManagementService {
public @NonNull Device save(@NonNull Device device) {
DeviceStatus status = device.getStatus();
checkDevice(device, true);
if (status == null) {
device.setStatus(DeviceStatus.NEW_DEVICE);
}
@ -55,14 +57,14 @@ public class DeviceManagementService {
throw new DeviceException(
"New device already has an Id: " + device.getId());
}
if (getById(device.getOs()).isPresent())
if (getById(device.getId()).isPresent())
throw new DeviceException(
"A device with the same Id already exists in repository: "+device.getId());
if (getByIpAddress(device.getIpAddress()).isPresent())
throw new DeviceException(
"A device with the same IP address already exists in repository: "+device.getIpAddress());
device.setCreationDate(Instant.now());
checkDevice(device);
checkDevice(device, false);
deviceRepository.save(device);
return device;
@ -73,7 +75,7 @@ public class DeviceManagementService {
if (result.isEmpty())
throw new DeviceException(
"Device with the Id does not exists in repository: "+device.getId());
checkDevice(device);
checkDevice(device, false);
device.setLastUpdateDate(Instant.now());
deviceRepository.save(device);
@ -82,12 +84,18 @@ public class DeviceManagementService {
new DeviceException("Device update failed for Device Id: "+device.getId()));
}
private void checkDevice(@NonNull Device device) {
public void checkDevice(@NonNull Device device, boolean dryRun) {
List<String> errors = new ArrayList<>();
if (StringUtils.isBlank(device.getId())) errors.add("Null or blank Id");
if (!dryRun && StringUtils.isBlank(device.getId())) errors.add("Null or blank Id");
if (StringUtils.isBlank(device.getOs())) errors.add("Null or blank OS");
if (StringUtils.isBlank(device.getOwner())) errors.add("Null or blank Owner");
if (device.getCreationDate()==null) errors.add("Null Creation date");
if (device.getStatus()==null) errors.add("Null Status");
if (StringUtils.isBlank(device.getIpAddress())) errors.add("Null or blank IP address");
if (!dryRun && StringUtils.isBlank(device.getNodeReference())) errors.add("Null or blank Node reference");
if (!dryRun && device.getCreationDate()==null) errors.add("Null Creation date");
if (!dryRun && device.getStatus()==null) errors.add("Null Status");
if (StringUtils.isBlank(device.getUsername())) errors.add("Null or blank Username");
if ((device.getPassword()==null || device.getPassword().length==0) &&
(device.getPublicKey()==null || device.getPublicKey().length==0)) errors.add("Null or blank Password and Public Key");
if (!errors.isEmpty()) {
throw new DeviceException(
String.format("Device spec has errors: %s\n%s",

View File

@ -134,13 +134,19 @@ public class RegistrationRequestProcessor implements IRegistrationRequestProcess
newRequests.size(), newRequests.stream().map(RegistrationRequest::getId).toList());
for (RegistrationRequest registrationRequest : newRequests) {
log.debug("processNewRequests: Requesting collection of device data for request with Id: {}", registrationRequest.getId());
Map<String, String> dataCollectionRequest = prepareRequestPayload(REQUEST_TYPE_DATA_COLLECTION, registrationRequest);
String jsonMessage = objectMapper.writer().writeValueAsString(dataCollectionRequest);
producer.send(createMessage(jsonMessage));
registrationRequest.setStatus(RegistrationRequestStatus.DATA_COLLECTION_REQUESTED);
registrationRequestService.update(registrationRequest);
log.debug("processNewRequests: Data collection request sent for request with Id: {}", registrationRequest.getId());
try {
log.debug("processNewRequests: Requesting collection of device data for request with Id: {}", registrationRequest.getId());
Map<String, String> dataCollectionRequest = prepareRequestPayload(REQUEST_TYPE_DATA_COLLECTION, registrationRequest);
String jsonMessage = objectMapper.writer().writeValueAsString(dataCollectionRequest);
producer.send(createMessage(jsonMessage));
registrationRequest.setStatus(RegistrationRequestStatus.DATA_COLLECTION_REQUESTED);
registrationRequestService.update(registrationRequest);
log.debug("processNewRequests: Data collection request sent for request with Id: {}", registrationRequest.getId());
} catch (Exception e) {
log.warn("processNewRequests: EXCEPTION while sending data collection request for request with Id: {}\n", registrationRequest.getId(), e);
registrationRequest.setStatus(RegistrationRequestStatus.DATA_COLLECTION_ERROR);
registrationRequestService.update(registrationRequest);
}
}
log.trace("processNewRequests: END");
@ -155,13 +161,24 @@ public class RegistrationRequestProcessor implements IRegistrationRequestProcess
onboardingRequests.size(), onboardingRequests.stream().map(RegistrationRequest::getId).toList());
for (RegistrationRequest registrationRequest : onboardingRequests) {
log.debug("processOnboardingRequests: Requesting device onboarding for request with Id: {}", registrationRequest.getId());
Map<String, String> dataCollectionRequest = prepareRequestPayload(REQUEST_TYPE_ONBOARDING, registrationRequest);
String jsonMessage = objectMapper.writer().writeValueAsString(dataCollectionRequest);
producer.send(createMessage(jsonMessage));
registrationRequest.setStatus(RegistrationRequestStatus.ONBOARDING_REQUESTED);
registrationRequestService.update(registrationRequest);
log.debug("processOnboardingRequests: Onboarding request sent for request with Id: {}", registrationRequest.getId());
try {
log.debug("processOnboardingRequests: Checking device before requesting onboarding for request with Id: {}", registrationRequest.getId());
deviceManagementService.checkDevice(
objectMapper.convertValue(registrationRequest.getDevice(), Device.class),
true);
log.debug("processOnboardingRequests: Requesting device onboarding for request with Id: {}", registrationRequest.getId());
Map<String, String> dataCollectionRequest = prepareRequestPayload(REQUEST_TYPE_ONBOARDING, registrationRequest);
String jsonMessage = objectMapper.writer().writeValueAsString(dataCollectionRequest);
producer.send(createMessage(jsonMessage));
registrationRequest.setStatus(RegistrationRequestStatus.ONBOARDING_REQUESTED);
registrationRequestService.update(registrationRequest);
log.debug("processOnboardingRequests: Onboarding request sent for request with Id: {}", registrationRequest.getId());
} catch (Exception e) {
log.warn("processOnboardingRequests: EXCEPTION while sending onboarding request for request with Id: {}\n", registrationRequest.getId(), e);
registrationRequest.setStatus(RegistrationRequestStatus.ONBOARDING_ERROR);
registrationRequestService.update(registrationRequest);
}
}
log.trace("processOnboardingRequests: END");
@ -349,13 +366,19 @@ public class RegistrationRequestProcessor implements IRegistrationRequestProcess
log.warn("processResponse: No device info found in message or it is of wrong type: id={}, obj={}", requestId, obj);
}
// If request status is SUCCESS then copy Device in monitoring subsystem
if (registrationRequest.getStatus() == RegistrationRequestStatus.SUCCESS) {
try {
copyDeviceToMonitoring(registrationRequest);
} catch (Exception e) {
log.warn("processResponse: EXCEPTION: while copying device to monitoring subsystem: request={}\n", registrationRequest, e);
registrationRequest.setStatus(RegistrationRequestStatus.ONBOARDING_ERROR);
registrationRequest.getMessages().add("Exception while copying device to monitoring subsystem: " + e.getMessage());
}
}
// Store changes
registrationRequestService.update(registrationRequest, false);
// If request status is SUCCESS then copy Device in monitoring subsystem
if (registrationRequest.getStatus()==RegistrationRequestStatus.SUCCESS) {
copyDeviceToMonitoring(registrationRequest);
}
} else {
log.warn("processResponse: Request not found: id={}", requestId);
}
@ -368,6 +391,7 @@ public class RegistrationRequestProcessor implements IRegistrationRequestProcess
device.setRequest(registrationRequest);
device.setRequestId(registrationRequest.getId());
device.getMessages().clear();
device.setNodeReference(registrationRequest.getNodeReference());
deviceManagementService.save(device);
}
}

View File

@ -107,7 +107,7 @@ public class RegistrationRequestController {
RegistrationRequest request = registrationRequestService.getById(id)
.orElseThrow(() -> new RegistrationRequestException("Not found registration request with id: " + id));
request.setStatus(_newStatus);
return registrationRequestService.update(request);
return registrationRequestService.update(request, false);
}
@PreAuthorize("hasAuthority('ROLE_ADMIN')")

View File

@ -109,7 +109,7 @@ public class RegistrationRequestService {
RegistrationRequestStatus status = registrationRequest.getStatus();
if (status==RegistrationRequestStatus.ONBOARDING_REQUESTED || status== RegistrationRequestStatus.SUCCESS)
throw new RegistrationRequestException(
"Registration request with the Id cannot be deleted due to its status: "
"Registration request with the Id cannot be edited or deleted due to its status: "
+ registrationRequest.getId() + ", status=" + status);
}

View File

@ -79,8 +79,10 @@ function updateRequestsList(asAdmin) {
<i class="fas fa-box"></i>
</button>
` : '';
adminActions += (isAdmin && (status!=='ONBOARDING_REQUESTED' && status!='SUCCESS')) ? `
<a href="/discovery/request/${reqId}/status/NEW_REQUEST" target="_blank">
adminActions += (isAdmin) ? `
<a href="#" target="_blank" onClick="
this.href = '/discovery/request/${reqId}/status/'+prompt('Change status to:', 'NEW_REQUEST');
">
<button class="btn btn-outline-danger btn-sm">
<i class="fas fa-fast-backward"></i>
</button>
@ -142,7 +144,7 @@ function deleteRequest(id) {
function processRequests() {
$.ajax({ url: '/discovery/request/process' })
.done(function(data, status) {
console.log('processRequests: OK: ', data);
//console.log('processRequests: OK: ', data);
})
.fail(function(xhr, status, error) {
console.error('processRequests: ERROR: ', status, error);
@ -153,7 +155,7 @@ function authorizeRequest(reqId, authorize) {
var authStr = authorize ? 'authorize' : 'reject';
$.ajax({ url: `/discovery/request/${reqId}/${authStr}` })
.done(function(data, status) {
console.log('authorizeRequest: OK: ', data);
//console.log('authorizeRequest: OK: ', data);
updateRequestsList(true);
})
.fail(function(xhr, status, error) {
@ -171,7 +173,7 @@ function archiveRequest(reqId) {
.done(function(data, status) {
console.log('archiveRequest: OK: ', data);
updateRequestsList(true);
alert(data);
//alert(data);
})
.fail(function(xhr, status, error) {
console.error('archiveRequest: ERROR: ', status, error);