Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Commit

Permalink
API-4160 restrict PUT endpoints (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
apeirats-va authored Jan 11, 2021
1 parent ac4aad9 commit 37d5a1b
Show file tree
Hide file tree
Showing 25 changed files with 287 additions and 180 deletions.
1 change: 1 addition & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
lombok.accessors.fluent=true
lombok.addLombokGeneratedAnnotation=true
lombok.nonNull.exceptionType=Guava
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.google.common.base.Preconditions.checkState;
import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang3.StringUtils.isBlank;

import com.fasterxml.jackson.databind.ObjectMapper;
import gov.va.api.health.autoconfig.configuration.JacksonConfig;
Expand Down Expand Up @@ -38,7 +39,6 @@
import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.Value;
import org.apache.commons.lang3.StringUtils;

public final class Populaterator {
private static final ObjectMapper MAPPER = JacksonConfig.createMapper();
Expand Down Expand Up @@ -118,7 +118,7 @@ private static void observation(@NonNull Connection connection) {
}

private static Instant parseDateTime(String datetime) {
if (StringUtils.isBlank(datetime)) {
if (isBlank(datetime)) {
return null;
}
String str = datetime.trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private static Ids ids() {
.questionnaireResponse("f003043a-9047-4c3a-b15b-a26c67f4e723")
.questionnaireResponseAuthor("1011537977V693883")
.questionnaireResponseSubject("1011537977V693883")
.questionnaireResponseGenerated("qr-generated")
.questionnaireResponseUpdates("4400ade6-4162-44e2-b470-c6b38c717f88")
.build();
}

Expand Down Expand Up @@ -141,7 +141,7 @@ static final class Ids {

@NonNull String questionnaireResponseSubject;

@NonNull String questionnaireResponseGenerated;
@NonNull String questionnaireResponseUpdates;
}

@Value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gov.va.api.health.patientgenerateddata.tests;

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPost;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;
import static gov.va.api.health.sentinel.EnvironmentAssumptions.assumeEnvironmentIn;

import gov.va.api.health.r4.api.datatypes.CodeableConcept;
Expand All @@ -25,14 +24,13 @@ static void assumeEnvironment() {
@Test
public void create_invalid() {
Observation observation = observation().id("123");
doPost(
"Observation", serializePayload(observation), "create invalid resource, existing id", 400);
doPost("Observation", observation, "create invalid resource, existing id", 400);
}

@Test
public void create_valid() {
Observation observation = observation();
doPost("Observation", serializePayload(observation), "create resource", 201);
doPost("Observation", observation, "create resource", 201);
}

private Observation observation() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gov.va.api.health.patientgenerateddata.tests;

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPost;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;
import static gov.va.api.health.patientgenerateddata.tests.SystemDefinitions.systemDefinition;
import static gov.va.api.health.sentinel.EnvironmentAssumptions.assumeEnvironmentIn;

Expand All @@ -28,23 +27,24 @@ public void create_invalid() {
// not an mpi id
String id = "123";
Patient patient = patient(id);
doPost("Patient", serializePayload(patient), "create invalid resource, bad mpi format", 400);
doPost("Patient", patient, "create invalid resource, bad mpi format", 400);
// no id
patient = patient(null);
doPost("Patient", serializePayload(patient), "create invalid resource, missing id", 400);
doPost("Patient", patient, "create invalid resource, missing id", 400);
// mismatch mpi id and identifier
id = "1111111111V111111";
patient = patient(id);
patient.identifier().add(identifier().system("http://va.gov/mpi"));
doPost(
"Patient", serializePayload(patient), "create invalid resource, mismatching MPI ids", 400);
doPost("Patient", patient, "create invalid resource, mismatching MPI ids", 400);
}

@Test
public void create_valid() {
var id = systemDefinition().ids().patientGenerated();
Patient patient = patient(id);
doPost("Patient", serializePayload(patient), "create resource", 201);
doPost("Patient", patient, "create resource", 201);
// duplicate is rejected
doPost("Patient", patient, "create resource (duplicate)", 400);
}

Identifier identifier() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gov.va.api.health.patientgenerateddata.tests;

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPost;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;
import static gov.va.api.health.sentinel.EnvironmentAssumptions.assumeEnvironmentIn;

import gov.va.api.health.r4.api.resources.Questionnaire;
Expand All @@ -21,17 +20,13 @@ static void assumeEnvironment() {
@Test
public void create_invalid() {
Questionnaire questionnaire = questionnaire().id("123");
doPost(
"Questionnaire",
serializePayload(questionnaire),
"create invalid resource, existing id",
400);
doPost("Questionnaire", questionnaire, "create invalid resource, existing id", 400);
}

@Test
public void create_valid() {
Questionnaire questionnaire = questionnaire();
doPost("Questionnaire", serializePayload(questionnaire), "create resource", 201);
doPost("Questionnaire", questionnaire, "create resource", 201);
}

private Questionnaire questionnaire() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gov.va.api.health.patientgenerateddata.tests;

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPost;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;
import static gov.va.api.health.sentinel.EnvironmentAssumptions.assumeEnvironmentIn;

import gov.va.api.health.r4.api.resources.QuestionnaireResponse;
Expand All @@ -23,16 +22,15 @@ public void create_invalid() {
QuestionnaireResponse questionnaireResponse = questionnaireResponse().id("123");
doPost(
"QuestionnaireResponse",
serializePayload(questionnaireResponse),
questionnaireResponse,
"create invalid resource, existing id",
400);
}

@Test
public void create_valid() {
QuestionnaireResponse questionnaireResponse = questionnaireResponse();
doPost(
"QuestionnaireResponse", serializePayload(questionnaireResponse), "create resource", 201);
doPost("QuestionnaireResponse", questionnaireResponse, "create resource", 201);
}

private QuestionnaireResponse questionnaireResponse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doGet;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPut;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;
import static gov.va.api.health.patientgenerateddata.tests.SystemDefinitions.systemDefinition;
import static gov.va.api.health.sentinel.EnvironmentAssumptions.assumeEnvironmentIn;
import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -26,24 +25,24 @@ static QuestionnaireResponse questionnaireResponse(String id) {
static void setup() {
// These tests alter data, but do not infinitely create more
// Do not run in SLA'd environments
assumeEnvironmentIn(
Environment.LOCAL, Environment.QA, Environment.STAGING, Environment.STAGING_LAB);
// assumeEnvironmentIn(
// Environment.LOCAL, Environment.QA, Environment.STAGING, Environment.STAGING_LAB);

var id = systemDefinition().ids().questionnaireResponseGenerated();
ExpectedResponse existing = doGet("application/json", "QuestionnaireResponse/" + id, null);
if (existing.response().statusCode() == 404) {
QuestionnaireResponse qr = questionnaireResponse(id);
doPut("QuestionnaireResponse/" + id, serializePayload(qr), "load initial resource", 201);
}
// Until a more permanent, update-specific QR Resource is made available, these tests should
// only run locally
assumeEnvironmentIn(Environment.LOCAL);

var id = systemDefinition().ids().questionnaireResponseUpdates();
doGet("application/json", "QuestionnaireResponse/" + id, 200);
}

@Test
void update_author() {
Instant now = Instant.now();
Reference ref = Reference.builder().reference("Resource/" + now.toString()).build();
var id = systemDefinition().ids().questionnaireResponseGenerated();
var id = systemDefinition().ids().questionnaireResponseUpdates();
QuestionnaireResponse qr = questionnaireResponse(id).author(ref);
doPut("QuestionnaireResponse/" + id, serializePayload(qr), "update author", 200);
doPut("QuestionnaireResponse/" + id, qr, "update author", 200);
ExpectedResponse persistedResponse =
doGet("application/json", "QuestionnaireResponse/" + id, 200);
QuestionnaireResponse persisted = persistedResponse.response().as(QuestionnaireResponse.class);
Expand All @@ -52,10 +51,10 @@ void update_author() {

@Test
void update_authored() {
var id = systemDefinition().ids().questionnaireResponseGenerated();
var id = systemDefinition().ids().questionnaireResponseUpdates();
Instant now = Instant.now().with(ChronoField.NANO_OF_SECOND, 0);
QuestionnaireResponse qr = questionnaireResponse(id).authored(now.toString());
doPut("QuestionnaireResponse/" + id, serializePayload(qr), "update authored date", 200);
doPut("QuestionnaireResponse/" + id, qr, "update authored date", 200);
ExpectedResponse persistedResponse =
doGet("application/json", "QuestionnaireResponse/" + id, 200);
QuestionnaireResponse persisted = persistedResponse.response().as(QuestionnaireResponse.class);
Expand All @@ -66,9 +65,9 @@ void update_authored() {
void update_subject() {
Instant now = Instant.now();
Reference ref = Reference.builder().reference("Resource/" + now.toString()).build();
var id = systemDefinition().ids().questionnaireResponseGenerated();
var id = systemDefinition().ids().questionnaireResponseUpdates();
QuestionnaireResponse qr = questionnaireResponse(id).subject(ref);
doPut("QuestionnaireResponse/" + id, serializePayload(qr), "update subject", 200);
doPut("QuestionnaireResponse/" + id, qr, "update subject", 200);
ExpectedResponse persistedResponse =
doGet("application/json", "QuestionnaireResponse/" + id, 200);
QuestionnaireResponse persisted = persistedResponse.response().as(QuestionnaireResponse.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static gov.va.api.health.patientgenerateddata.tests.SystemDefinitions.systemDefinition;
import static gov.va.api.health.sentinel.ExpectedResponse.logAllWithTruncatedBody;

import com.fasterxml.jackson.databind.ObjectMapper;
import gov.va.api.health.autoconfig.configuration.JacksonConfig;
import gov.va.api.health.sentinel.ExpectedResponse;
import io.restassured.RestAssured;
Expand All @@ -13,6 +14,8 @@

@Slf4j
public class RequestUtils {
private static final ObjectMapper MAPPER = JacksonConfig.createMapper();

public static ExpectedResponse doGet(
String acceptHeader, String request, Integer expectedStatus) {
SystemDefinitions.Service svc = systemDefinition().r4();
Expand All @@ -39,8 +42,9 @@ public static ExpectedResponse doGet(
return response;
}

@SneakyThrows
public static ExpectedResponse doPost(
String request, String payload, String description, Integer expectedStatus) {
String request, Object payload, String description, Integer expectedStatus) {
SystemDefinitions.Service svc = systemDefinition().r4();
RequestSpecification spec =
RestAssured.given()
Expand All @@ -49,7 +53,7 @@ public static ExpectedResponse doPost(
.relaxedHTTPSValidation()
.header("Authorization", "Bearer " + System.getProperty("access-token", "unset"))
.header("Content-Type", "application/json")
.body(payload);
.body(MAPPER.writeValueAsString(payload));
log.info(
"Expect {} POST '{}' is status code ({})",
svc.apiPath() + request,
Expand All @@ -64,8 +68,9 @@ public static ExpectedResponse doPost(
return response;
}

@SneakyThrows
public static ExpectedResponse doPut(
String request, String payload, String description, Integer expectedStatus) {
String request, Object payload, String description, Integer expectedStatus) {
SystemDefinitions.Service svc = systemDefinition().r4();
RequestSpecification spec =
RestAssured.given()
Expand All @@ -74,7 +79,7 @@ public static ExpectedResponse doPut(
.relaxedHTTPSValidation()
.header("Authorization", "Bearer " + System.getProperty("access-token", "unset"))
.header("Content-Type", "application/json")
.body(payload);
.body(MAPPER.writeValueAsString(payload));
log.info(
"Expect {} PUT '{}' is status code ({})",
svc.apiPath() + request,
Expand All @@ -88,9 +93,4 @@ public static ExpectedResponse doPut(
}
return response;
}

@SneakyThrows
public static String serializePayload(Object payload) {
return JacksonConfig.createMapper().writeValueAsString(payload);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gov.va.api.health.patientgenerateddata.tests;

import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.doPut;
import static gov.va.api.health.patientgenerateddata.tests.RequestUtils.serializePayload;

import com.fasterxml.jackson.databind.ObjectMapper;
import gov.va.api.health.autoconfig.configuration.JacksonConfig;
Expand Down Expand Up @@ -33,7 +32,7 @@ private static <T extends Resource> void refresh(String folder, Class<T> clazz)
new File(baseDir() + "/../patient-generated-data-synthetic/src/test/resources/" + folder)
.listFiles()) {
T obj = MAPPER.readValue(f, clazz);
doPut(clazz.getSimpleName() + "/" + obj.id(), serializePayload(obj), "refresh", null);
doPut(clazz.getSimpleName() + "/" + obj.id(), obj, "refresh", null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public NotFound(String message) {
}

public static final class BadRequest extends RuntimeException {
public BadRequest(String message) {
super(message);
}

public BadRequest(String message, Throwable cause) {
super(message, cause);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

@Configuration
public class JacksonMapperConfig {

private final MagicReferenceConfig magicReferences;

@Autowired
Expand All @@ -18,7 +17,6 @@ public JacksonMapperConfig(MagicReferenceConfig magicReferences) {

@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = JacksonConfig.createMapper();
return magicReferences.configure(mapper);
return magicReferences.configure(JacksonConfig.createMapper());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gov.va.api.health.patientgenerateddata;

import static org.apache.commons.lang3.StringUtils.isBlank;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -13,7 +15,6 @@
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand All @@ -35,7 +36,7 @@ private QualifiedReferenceWriter(BeanPropertyWriter base) {
}

private String qualify(String reference) {
if (StringUtils.isBlank(reference)) {
if (isBlank(reference)) {
return null;
}
if (reference.startsWith("http")) {
Expand Down
Loading

0 comments on commit 37d5a1b

Please sign in to comment.