use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.
the class AssessmentService method importAssessment.
/**
* Takes an assessment in the shared context and clones it into the caller's local context, using the
* specified organization as the new owner of the local assessment (must be an organization the caller
* is associated to). If the identifier already exists in this app, the revision number is adjusted
* appropriately. The origin GUID is set to the GUID of the shared assessment.
*/
public Assessment importAssessment(String appId, String ownerId, String newIdentifier, String guid) {
checkArgument(isNotBlank(appId));
checkArgument(isNotBlank(guid));
if (ownerId == null) {
ownerId = RequestContext.get().getCallerOrgMembership();
}
if (isBlank(ownerId)) {
throw new BadRequestException("ownerId parameter is required");
}
CAN_IMPORT_SHARED_ASSESSMENTS.checkAndThrow(ORG_ID, ownerId);
Assessment sharedAssessment = getAssessmentByGuid(SHARED_APP_ID, null, guid);
AssessmentConfig sharedConfig = configService.getSharedAssessmentConfig(SHARED_APP_ID, guid);
// Check organization because admins and superadmins can provide anything, it's not
// inherited from the caller's org membership (if any).
organizationService.getOrganization(appId, ownerId);
if (isNotBlank(newIdentifier)) {
sharedAssessment.setIdentifier(newIdentifier);
}
// Figure out what revision this should be in the new app context if the identifier already exists
int revision = nextRevisionNumber(appId, sharedAssessment.getIdentifier());
sharedAssessment.setOriginGuid(sharedAssessment.getGuid());
sharedAssessment.setGuid(generateGuid());
sharedAssessment.setRevision(revision);
sharedAssessment.setOwnerId(ownerId);
return dao.importAssessment(appId, sharedAssessment, sharedConfig);
}
use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.
the class HealthDataService method updateRecordsWithExporterStatus.
/**
* returns received list of record Ids after updating
* @param recordExportStatusRequest
* POJO contains: a lit of health record ids, not upload ids and
* an Synapse Exporter Status with value either NOT_EXPORTED or SUCCEEDED
* @return updated health record ids list
*/
public List<String> updateRecordsWithExporterStatus(RecordExportStatusRequest recordExportStatusRequest) {
Validate.entityThrowingException(exporterStatusValidator, recordExportStatusRequest);
List<String> healthRecordIds = recordExportStatusRequest.getRecordIds();
HealthDataRecord.ExporterStatus synapseExporterStatus = recordExportStatusRequest.getSynapseExporterStatus();
if (healthRecordIds.size() > MAX_NUM_RECORD_IDS) {
throw new BadRequestException("Size of the record ids list exceeds the limit.");
}
List<String> updatedRecordIds = healthRecordIds.stream().map(id -> {
HealthDataRecord record = getRecordById(id);
if (record == null) {
throw new NotFoundException("The record: " + id + " cannot be found in our database.");
}
record.setSynapseExporterStatus(synapseExporterStatus);
return createOrUpdateRecord(record);
}).collect(Collectors.toList());
return updatedRecordIds;
}
use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.
the class HealthDataService method submitHealthData.
/* HEALTH DATA SUBMISSION */
/**
* Synchronous health data API. Used to submit small health data payloads (such as survey responses) without
* incurring the overhead of creating a bunch of small files to upload to S3.
*/
public HealthDataRecord submitHealthData(String appId, StudyParticipant participant, HealthDataSubmission healthDataSubmission) throws IOException, UploadValidationException {
// validate health data submission
if (healthDataSubmission == null) {
throw new InvalidEntityException("Health data submission cannot be null");
}
Validate.entityThrowingException(HealthDataSubmissionValidator.INSTANCE, healthDataSubmission);
// Generate a new uploadId.
String uploadId = BridgeUtils.generateGuid();
// construct health data record
HealthDataRecord record = makeRecordFromSubmission(appId, participant, healthDataSubmission);
// get schema
UploadSchema schema = getSchemaForSubmission(appId, healthDataSubmission);
if (schema != null) {
// sanitize field names in the data node
JsonNode sanitizedData = sanitizeFieldNames(healthDataSubmission.getData());
// Filter data fields and attachments based on schema fields.
filterAttachments(uploadId, schema, sanitizedData, record);
}
// Construct UploadValidationContext for the remaining upload handlers. We don't need all the fields, just the
// ones that these handlers will be using.
UploadValidationContext uploadValidationContext = new UploadValidationContext();
uploadValidationContext.setHealthCode(participant.getHealthCode());
uploadValidationContext.setHealthDataRecord(record);
uploadValidationContext.setAppId(appId);
// For back-compat reasons, we need to make a dummy upload to store the uploadId. This will never be persisted.
// We just need a way to signal the Upload Validation pipeline to use this uploadId.
Upload upload = Upload.create();
upload.setUploadId(uploadId);
uploadValidationContext.setUpload(upload);
// Strict Validation Handler. If this throws, this is an invalid upload (400).
try {
strictValidationHandler.handle(uploadValidationContext);
} catch (UploadValidationException ex) {
throw new BadRequestException(ex);
}
// Transcribe Consent.
transcribeConsentHandler.handle(uploadValidationContext);
// Upload raw JSON as the raw data attachment. This is different from how the upload validation handles it.
// Attachment ID is "[uploadId]-raw.json".
String rawDataAttachmentId = uploadId + RAW_ATTACHMENT_SUFFIX;
String rawDataValue = BridgeObjectMapper.get().writerWithDefaultPrettyPrinter().writeValueAsString(healthDataSubmission.getData());
byte[] rawDataBytes = rawDataValue.getBytes(Charsets.UTF_8);
uploadFileHelper.uploadBytesAsAttachment(rawDataAttachmentId, rawDataBytes);
record.setRawDataAttachmentId(rawDataAttachmentId);
// Upload Artifacts.
uploadArtifactsHandler.handle(uploadValidationContext);
// (depending on attachments). So we need to use the record ID to fetch the record again and return it.
return getRecordById(uploadValidationContext.getRecordId());
}
use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.
the class SmsService method optInPhoneNumber.
/**
* Opt a phone number back in if it is opted out. This is only used when a new account is created, generally in
* a new app. User ID is used for logging.
*/
public void optInPhoneNumber(String userId, Phone phone) {
if (StringUtils.isBlank(userId)) {
throw new BadRequestException("userId is required");
}
if (phone == null) {
throw new BadRequestException("phone is required");
}
if (!Phone.isValid(phone)) {
throw new BadRequestException("phone is invalid");
}
// Check if phone number is opted out.
CheckIfPhoneNumberIsOptedOutRequest checkRequest = new CheckIfPhoneNumberIsOptedOutRequest().withPhoneNumber(phone.getNumber());
CheckIfPhoneNumberIsOptedOutResult checkResult = snsClient.checkIfPhoneNumberIsOptedOut(checkRequest);
if (Boolean.TRUE.equals(checkResult.isOptedOut())) {
LOG.info("Opting in user " + userId + " for SMS messages");
// User was previously opted out. They created a new account (almost certainly in a new app). We need
// to opt them back in. Note that according to AWS, this can only be done once every 30 days to prevent
// abuse.
OptInPhoneNumberRequest optInRequest = new OptInPhoneNumberRequest().withPhoneNumber(phone.getNumber());
snsClient.optInPhoneNumber(optInRequest);
}
}
use of org.sagebionetworks.bridge.exceptions.BadRequestException in project BridgeServer2 by Sage-Bionetworks.
the class StudyActivityEventService method deleteEvent.
/**
* Delete an event if it is mutable (basically only custom events). If the event was the originating
* (triggering) event for a set of study burst events, those events will be deleted as well.
*
* @param event
* the event to be deleted
* @param showError
* if false (the default), this method returns quietly regardless of the outcome of publishing
* the event. If true, it will throw a BadRequestException if any event cannot be deleted.
*/
public void deleteEvent(StudyActivityEvent event, boolean showError) {
checkNotNull(event);
Validate.entityThrowingException(DELETE_INSTANCE, event);
StudyActivityEvent mostRecent = dao.getRecentStudyActivityEvent(event.getUserId(), event.getStudyId(), event.getEventId());
if (event.getUpdateType().canDelete(mostRecent, event)) {
dao.deleteEvent(event);
Study study = studyService.getStudy(event.getAppId(), event.getStudyId(), true);
Schedule2 schedule = scheduleService.getScheduleForStudy(study.getAppId(), study).orElse(null);
if (schedule != null) {
deleteStudyBurstEvents(schedule, event);
}
CacheKey cacheKey = CacheKey.etag(StudyActivityEvent.class, event.getUserId());
cacheProvider.setObject(cacheKey, getCreatedOn());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("User " + event.getUserId() + " failed to delete study event: " + event.getEventId());
}
if (showError) {
throw new BadRequestException("Study event failed to delete: " + event.getEventId() + ".");
}
}
}
Aggregations