Search in sources :

Example 1 with HealthDataSubmission

use of org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission in project BridgeServer2 by Sage-Bionetworks.

the class HealthDataServiceSubmitHealthDataTest method submitHealthDataBySchema.

@Test
public void submitHealthDataBySchema() throws Exception {
    // mock schema service
    List<UploadFieldDefinition> fieldDefList = ImmutableList.of(new UploadFieldDefinition.Builder().withName("sanitize____this").withType(UploadFieldType.STRING).build(), new UploadFieldDefinition.Builder().withName("no-value-field").withType(UploadFieldType.STRING).withRequired(false).build(), new UploadFieldDefinition.Builder().withName("null-value-field").withType(UploadFieldType.STRING).withRequired(false).build(), new UploadFieldDefinition.Builder().withName("attachment-field").withType(UploadFieldType.ATTACHMENT_V2).build(), new UploadFieldDefinition.Builder().withName("normal-field").withType(UploadFieldType.STRING).build());
    schema.setFieldDefinitions(fieldDefList);
    // setup input
    ObjectNode inputData = BridgeObjectMapper.get().createObjectNode();
    inputData.put("sanitize!@#$this", "sanitize this value");
    inputData.putNull("null-value-field");
    inputData.put("attachment-field", "attachment field value");
    inputData.put("normal-field", "normal field value");
    inputData.put("non-schema-field", "this is not in the schema");
    ObjectNode inputMetadata = BridgeObjectMapper.get().createObjectNode();
    inputMetadata.put("sample-metadata-key", "sample-metadata-value");
    HealthDataSubmission submission = makeValidBuilderWithSchema().withData(inputData).withMetadata(inputMetadata).build();
    // execute
    HealthDataRecord svcOutputRecord = svc.submitHealthData(TEST_APP_ID, PARTICIPANT, submission);
    // verify that we return the record returned by the internal getRecordById() call.
    assertSame(svcOutputRecord, createdRecord);
    // Verify strict validation handler called. While we're at it, verify that we constructed the context and
    // record correctly.
    ArgumentCaptor<UploadValidationContext> contextCaptor = ArgumentCaptor.forClass(UploadValidationContext.class);
    verify(mockStrictValidationHandler).handle(contextCaptor.capture());
    UploadValidationContext context = contextCaptor.getValue();
    assertEquals(context.getHealthCode(), HEALTH_CODE);
    assertEquals(context.getAppId(), TEST_APP_ID);
    // We generate an upload ID and use it for the record ID.
    String uploadId = context.getUploadId();
    assertNotNull(uploadId);
    assertEquals(context.getRecordId(), uploadId);
    // We have one attachment. This is text because we passed in text. This will normally be arrays or objects.
    ArgumentCaptor<JsonNode> attachmentNodeCaptor = ArgumentCaptor.forClass(JsonNode.class);
    verify(mockUploadFileHelper).uploadJsonNodeAsAttachment(attachmentNodeCaptor.capture(), eq(uploadId), eq("attachment-field"));
    JsonNode attachmentNode = attachmentNodeCaptor.getValue();
    assertEquals(attachmentNode.textValue(), "attachment field value");
    // validate the created record
    HealthDataRecord contextRecord = context.getHealthDataRecord();
    assertEquals(contextRecord.getAppVersion(), APP_VERSION);
    assertEquals(contextRecord.getPhoneInfo(), PHONE_INFO);
    assertEquals(contextRecord.getSchemaId(), SCHEMA_ID);
    assertEquals(contextRecord.getSchemaRevision().intValue(), SCHEMA_REV);
    assertEquals(contextRecord.getHealthCode(), HEALTH_CODE);
    assertEquals(contextRecord.getAppId(), TEST_APP_ID);
    assertEquals(contextRecord.getUploadDate(), MOCK_NOW_DATE);
    assertEquals(contextRecord.getUploadedOn().longValue(), MOCK_NOW_MILLIS);
    assertEquals(contextRecord.getCreatedOn().longValue(), CREATED_ON_MILLIS);
    assertEquals(contextRecord.getCreatedOnTimeZone(), CREATED_ON_TIMEZONE);
    // validate the sanitized data (includes attachments with attachment ID)
    JsonNode sanitizedData = contextRecord.getData();
    assertEquals(sanitizedData.size(), 3);
    assertEquals(sanitizedData.get("sanitize____this").textValue(), "sanitize this value");
    assertEquals(sanitizedData.get("attachment-field"), ATTACHMENT_ID_NODE);
    assertEquals(sanitizedData.get("normal-field").textValue(), "normal field value");
    // validate app version and phone info in metadata
    JsonNode metadata = contextRecord.getMetadata();
    assertEquals(metadata.size(), 2);
    assertEquals(metadata.get(UploadUtil.FIELD_APP_VERSION).textValue(), APP_VERSION);
    assertEquals(metadata.get(UploadUtil.FIELD_PHONE_INFO).textValue(), PHONE_INFO);
    // validate client-submitted metadata (userMetadata)
    JsonNode userMetadata = contextRecord.getUserMetadata();
    assertEquals(userMetadata.size(), 1);
    assertEquals(userMetadata.get("sample-metadata-key").textValue(), "sample-metadata-value");
    // Validate raw data submitted to S3
    String expectedRawDataAttachmentId = uploadId + HealthDataService.RAW_ATTACHMENT_SUFFIX;
    ArgumentCaptor<byte[]> rawBytesCaptor = ArgumentCaptor.forClass(byte[].class);
    verify(mockUploadFileHelper).uploadBytesAsAttachment(eq(expectedRawDataAttachmentId), rawBytesCaptor.capture());
    assertEquals(contextRecord.getRawDataAttachmentId(), expectedRawDataAttachmentId);
    byte[] rawBytes = rawBytesCaptor.getValue();
    JsonNode rawJsonNode = BridgeObjectMapper.get().readTree(rawBytes);
    assertEquals(rawJsonNode, inputData);
    // validate the other handlers are called
    verify(mockTranscribeConsentHandler).handle(context);
    verify(mockUploadArtifactsHandler).handle(context);
    // We get the record back using the upload ID.
    verify(svc).getRecordById(uploadId);
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) UploadValidationContext(org.sagebionetworks.bridge.upload.UploadValidationContext) JsonNode(com.fasterxml.jackson.databind.JsonNode) UploadFieldDefinition(org.sagebionetworks.bridge.models.upload.UploadFieldDefinition) HealthDataSubmission(org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission) HealthDataRecord(org.sagebionetworks.bridge.models.healthdata.HealthDataRecord) Test(org.testng.annotations.Test)

Example 2 with HealthDataSubmission

use of org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission in project BridgeServer2 by Sage-Bionetworks.

the class HealthDataServiceSubmitHealthDataTest method strictValidationThrows.

@Test(expectedExceptions = BadRequestException.class)
public void strictValidationThrows() throws Exception {
    // mock schema service
    List<UploadFieldDefinition> fieldDefList = ImmutableList.of(new UploadFieldDefinition.Builder().withName("simple-field").withType(UploadFieldType.INT).build());
    schema.setFieldDefinitions(fieldDefList);
    // mock handlers - Only StrictValidationHandler will be called. Also, since we're not calling the actual
    // StrictValidationHandler, we need to make it throw.
    doThrow(UploadValidationException.class).when(mockStrictValidationHandler).handle(any());
    // setup input
    ObjectNode inputData = BridgeObjectMapper.get().createObjectNode();
    inputData.put("simple-field", "not an int");
    HealthDataSubmission submission = makeValidBuilderWithSchema().withData(inputData).build();
    // execute - This throws.
    svc.submitHealthData(TEST_APP_ID, PARTICIPANT, submission);
}
Also used : UploadFieldDefinition(org.sagebionetworks.bridge.models.upload.UploadFieldDefinition) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) HealthDataSubmission(org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission) Test(org.testng.annotations.Test)

Example 3 with HealthDataSubmission

use of org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission in project BridgeServer2 by Sage-Bionetworks.

the class HealthDataServiceSubmitHealthDataTest method invalidSubmission.

@Test(expectedExceptions = InvalidEntityException.class)
public void invalidSubmission() throws Exception {
    HealthDataSubmission submission = makeValidBuilderWithSchema().withData(null).build();
    svc.submitHealthData(TEST_APP_ID, PARTICIPANT, submission);
}
Also used : HealthDataSubmission(org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission) Test(org.testng.annotations.Test)

Example 4 with HealthDataSubmission

use of org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission in project BridgeServer2 by Sage-Bionetworks.

the class SmsServiceTest method verifyHealthData.

private void verifyHealthData(StudyParticipant expectedParticipant, DateTimeZone expectedTimeZone, SmsType expectedSmsType, String expectedMessage) throws Exception {
    ArgumentCaptor<HealthDataSubmission> healthDataCaptor = ArgumentCaptor.forClass(HealthDataSubmission.class);
    verify(mockHealthDataService).submitHealthData(eq(TEST_APP_ID), same(expectedParticipant), healthDataCaptor.capture());
    HealthDataSubmission healthData = healthDataCaptor.getValue();
    // Verify simple attributes.
    assertEquals(healthData.getAppVersion(), SmsService.BRIDGE_SERVER_APP_VERSION);
    assertEquals(healthData.getPhoneInfo(), SmsService.BRIDGE_SERVER_PHONE_INFO);
    assertEquals(healthData.getSchemaId(), SmsService.MESSAGE_LOG_SCHEMA_ID);
    assertEquals(healthData.getSchemaRevision().intValue(), SmsService.MESSAGE_LOG_SCHEMA_REV);
    DateTime createdOn = healthData.getCreatedOn();
    assertEquals(createdOn.getMillis(), MOCK_NOW_MILLIS);
    assertEquals(createdOn.getZone().getOffset(createdOn), expectedTimeZone.getOffset(createdOn));
    // Assert health data.
    JsonNode healthDataNode = healthData.getData();
    assertEquals(healthDataNode.get(SmsService.FIELD_NAME_SMS_TYPE).textValue(), expectedSmsType.getValue());
    assertEquals(healthDataNode.get(SmsService.FIELD_NAME_MESSAGE_BODY).textValue(), expectedMessage);
    // sentOn is createdOn in string form.
    assertEquals(healthDataNode.get(SmsService.FIELD_NAME_SENT_ON).textValue(), createdOn.toString());
}
Also used : HealthDataSubmission(org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission) JsonNode(com.fasterxml.jackson.databind.JsonNode) DateTime(org.joda.time.DateTime)

Example 5 with HealthDataSubmission

use of org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission in project BridgeServer2 by Sage-Bionetworks.

the class HealthDataController method submitHealthData.

/**
 * API to allow consented users to submit health data in a synchronous API, instead of using the asynchronous
 * upload API. This is most beneficial for small data sets, like simple surveys. This API returns the health data
 * record produced from this submission, which includes the record ID.
 */
@PostMapping(path = "/v3/healthdata", produces = { APPLICATION_JSON_UTF8_VALUE })
@ResponseStatus(HttpStatus.CREATED)
public String submitHealthData() throws IOException, UploadValidationException {
    // Submit health data.
    UserSession session = getAuthenticatedAndConsentedSession();
    HealthDataSubmission healthDataSubmission = parseJson(HealthDataSubmission.class);
    HealthDataRecord savedRecord = healthDataService.submitHealthData(session.getAppId(), session.getParticipant(), healthDataSubmission);
    // Write record ID into the metrics, for logging and diagnostics.
    Metrics metrics = getMetrics();
    if (metrics != null) {
        metrics.setRecordId(savedRecord.getId());
    }
    // Record upload time to user's request info. This allows us to track the last time the user submitted.
    RequestInfo requestInfo = getRequestInfoBuilder(session).withUploadedOn(DateUtils.getCurrentDateTime()).build();
    requestInfoService.updateRequestInfo(requestInfo);
    // Return the record produced by this submission. Filter out Health Code, of course.
    return HealthDataRecord.PUBLIC_RECORD_WRITER.writeValueAsString(savedRecord);
}
Also used : Metrics(org.sagebionetworks.bridge.models.Metrics) HealthDataSubmission(org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission) UserSession(org.sagebionetworks.bridge.models.accounts.UserSession) HealthDataRecord(org.sagebionetworks.bridge.models.healthdata.HealthDataRecord) RequestInfo(org.sagebionetworks.bridge.models.RequestInfo) PostMapping(org.springframework.web.bind.annotation.PostMapping) ResponseStatus(org.springframework.web.bind.annotation.ResponseStatus)

Aggregations

HealthDataSubmission (org.sagebionetworks.bridge.models.healthdata.HealthDataSubmission)42 Test (org.testng.annotations.Test)36 DateRangeResourceList (org.sagebionetworks.bridge.models.DateRangeResourceList)9 StatusMessage (org.sagebionetworks.bridge.models.StatusMessage)9 HealthDataRecord (org.sagebionetworks.bridge.models.healthdata.HealthDataRecord)7 JsonNode (com.fasterxml.jackson.databind.JsonNode)6 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)6 Account (org.sagebionetworks.bridge.models.accounts.Account)6 ReportData (org.sagebionetworks.bridge.models.reports.ReportData)6 SignIn (org.sagebionetworks.bridge.models.accounts.SignIn)5 Appointment (org.hl7.fhir.dstu3.model.Appointment)3 StudyParticipant (org.sagebionetworks.bridge.models.accounts.StudyParticipant)3 UploadFieldDefinition (org.sagebionetworks.bridge.models.upload.UploadFieldDefinition)3 UploadValidationContext (org.sagebionetworks.bridge.upload.UploadValidationContext)3 IOException (java.io.IOException)2 DateTime (org.joda.time.DateTime)2 BridgeServiceException (org.sagebionetworks.bridge.exceptions.BridgeServiceException)2 Metrics (org.sagebionetworks.bridge.models.Metrics)2 RequestInfo (org.sagebionetworks.bridge.models.RequestInfo)2 UserSession (org.sagebionetworks.bridge.models.accounts.UserSession)2