tryDeployment method
Tries to deploy the study if it's ready to be deployed by registering
the client device using registration and verifying the study is
ready for deployment on this device.
In case already deployed, nothing happens.
Throws IllegalArgumentException if:
- a deployment with study deployment ID matching this
studydoes not exist - device role name of
studyis not present in the deployment or is already registered and a differentregistrationis specified registrationof this client is invalid for the expected device role name or has a device ID which is already in use by the registration of a different device.
Implementation
Future<void> tryDeployment(
Study study,
DeviceRegistration registration,
) async {
final studyDeploymentId = study.studyDeploymentId;
final deviceRoleName = study.deviceRoleName;
StudyDeploymentStatus? deploymentStatus = await getStudyDeploymentStatus(study);
// A missing status is already reported by [getStudyDeploymentStatus].
if (deploymentStatus == null ||
deploymentStatus.status == StudyDeploymentStatusTypes.Running) {
return;
}
try {
deploymentStatus =
await deploymentService.registerDevice(
studyDeploymentId,
deviceRoleName,
registration,
) ??
deploymentStatus;
} catch (error) {
// The device may already be registered, e.g. after an app restart or
// reinstallation. Report it, but keep obtaining the deployment.
study.deploymentError(
"$runtimeType - Error registering '$deviceRoleName' as primary device "
"in study deployment '$studyDeploymentId'.\n$error",
);
}
// Update study with new deployment status.
study.deploymentStatusReceived(deploymentStatus);
final deviceStatus = deploymentStatus!.getDeviceStatusByRoleName(
deviceRoleName,
);
// The following statement is from CARP Core Kotlin.
// However, this has been removed here in order to allow for re-deployment,
// i.e., cases where we want to refresh the deployment information from the
// deployment service. This is needed on app restart and app reinstallation,
// where the device might already be registered but the deployment information is lost.
//
// // Early out in case state indicates the device is already deployed.
// if (deviceStatus.status == DeviceDeploymentStatusTypes.Deployed) return;
// Early out in case state indicates that deployment cannot yet be obtained.
if (!deviceStatus.canObtainDeviceDeployment) return;
// Get deployment information.
final device = deviceStatus.device;
PrimaryDeviceDeployment? deployment;
try {
deployment = await deploymentService.getDeviceDeploymentFor(
studyDeploymentId,
deviceRoleName,
);
} catch (error) {
study.deploymentError(
"$runtimeType - Error getting deployment information.\n$error",
);
// deploymentStatus = null;
return;
}
if (deployment == null) {
study.deploymentError(
"$runtimeType - Deployment for device role name '$deviceRoleName' "
"in study deployment '$studyDeploymentId' is not available.",
);
return;
}
if (deployment.deviceConfiguration.roleName != deviceRoleName) {
study.deploymentError(
"The device role name of the deployment is '${deployment.deviceConfiguration.roleName}', "
"which does not match the requested device role name '$deviceRoleName'.",
);
return;
}
// Notify the study that the deployment has been received
study.deviceDeploymentReceived(deployment);
final remainingDevicesToRegister = deploymentStatus.deviceStatusList
.map((status) => status.device)
.where(
(it) =>
(deviceStatus.remainingDevicesToRegisterBeforeDeployment ?? [])
.contains(it.roleName),
)
.toSet();
// Stop here in case other devices need to be registered before being able to complete deployment.
if (remainingDevicesToRegister.isNotEmpty) return;
// Notify deployment service of successful deployment.
try {
final deployedStatus = await deploymentService.deviceDeployed(
studyDeploymentId,
device.roleName,
deployment.lastUpdatedOn,
);
// Update study with new deployment status and deployment information.
if (deployedStatus != null) {
study.deploymentStatusReceived(deployedStatus);
study.deploymentUpdated(
"$runtimeType - Deployment '$studyDeploymentId' marked as deployed - status: ${deployedStatus.status?.name}",
);
}
} catch (error) {
// we only print a warning - there is a bug in CAWS - see issue #561
print(
"$runtimeType - Error marking deployment '$studyDeploymentId' as deployed.\n$error",
);
}
}