Skip to content

Commit

Permalink
Fix #2074 : Unify RESTful API for Patient Management services for own…
Browse files Browse the repository at this point in the history
… and external archives
  • Loading branch information
vrindanayak committed Jul 9, 2019
1 parent c7bd005 commit e374091
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonParsingException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Pattern;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.*;
import java.net.ConnectException;
import java.nio.charset.StandardCharsets;

/**
* @author Vrinda Nayak <[email protected]>
Expand Down Expand Up @@ -112,9 +114,31 @@ public Response createPatient(InputStream in) {
}

@PUT
@Path("/{priorPatientID}")
@Consumes({"application/dicom+json,application/json"})
@Produces("application/json")
public Response updatePatient(InputStream in) {
public Response updatePatient(
@PathParam("priorPatientID") IDWithIssuer priorPatientID,
@QueryParam("merge") @Pattern(regexp = "true|false") @DefaultValue("false") String merge,
InputStream in) {
logRequest();
String msgType = "ADT^A31^ADT_A05";
PatientMgtContext ctx = toPatientMgtContext(toAttributes(in));
IDWithIssuer patientID = ctx.getPatientID();
boolean mergePatients = Boolean.parseBoolean(merge);
if (!patientID.equals(priorPatientID)) {
ctx.setPreviousAttributes(priorPatientID.exportPatientIDWithIssuer(null));
msgType = mergePatients ? "ADT^A40^ADT_A39" : "ADT^A47^ADT_A30";
} else if (mergePatients)
return errResponse("Circular merge of patients not allowed.", Response.Status.BAD_REQUEST);

return scheduleOrSendHL7(msgType, ctx);
}

@PUT
@Consumes({"application/dicom+json,application/json"})
@Produces("application/json")
public Response updatePatient1(InputStream in) {
logRequest();
return scheduleOrSendHL7("ADT^A31^ADT_A05", toPatientMgtContext(toAttributes(in)));
}
Expand All @@ -128,7 +152,7 @@ private PatientMgtContext toPatientMgtContext(Attributes attrs) {

private Attributes toAttributes(InputStream in) {
try {
return new JSONReader(Json.createParser(new InputStreamReader(in, "UTF-8")))
return new JSONReader(Json.createParser(new InputStreamReader(in, StandardCharsets.UTF_8)))
.readDataset(null);
} catch (JsonParsingException e) {
throw new WebApplicationException(errResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,62 +270,76 @@ public void deleteStudy(@PathParam("StudyUID") String studyUID) {
public String createPatient(InputStream in) {
logRequest();
ArchiveAEExtension arcAE = getArchiveAE();
Attributes attrs = toAttributes(in);
if (attrs.containsValue(Tag.PatientID))
throw new WebApplicationException(
errResponse("Patient ID in message body", Response.Status.BAD_REQUEST));

try {
idService.newPatientID(attrs);
PatientMgtContext ctx = patientService.createPatientMgtContextWEB(HttpServletRequestInfo.valueOf(request));
ctx.setAttributes(attrs);
ctx.setAttributeUpdatePolicy(Attributes.UpdatePolicy.REPLACE);
PatientMgtContext ctx = patientMgtCtx(in);
if (!ctx.getAttributes().containsValue(Tag.PatientID)) {
idService.newPatientID(ctx.getAttributes());
ctx.setPatientID(IDWithIssuer.pidOf(ctx.getAttributes()));
}
patientService.updatePatient(ctx);
rsForward.forward(RSOperation.CreatePatient, arcAE, attrs, request);
rsForward.forward(RSOperation.CreatePatient, arcAE, ctx.getAttributes(), request);
rsHL7Sender.sendHL7Message("ADT^A28^ADT_A05", ctx);
return "{\"PatientID\":\"" + attrs.getString(Tag.PatientID) + "\"}";
return "{\"PatientID\":\"" + ctx.getAttributes().getString(Tag.PatientID) + "\"}";
} catch (Exception e) {
throw new WebApplicationException(
errResponseAsTextPlain(exceptionAsString(e), Response.Status.INTERNAL_SERVER_ERROR));
}
}

private PatientMgtContext patientMgtCtx(InputStream in) {
PatientMgtContext ctx = patientService.createPatientMgtContextWEB(HttpServletRequestInfo.valueOf(request));
ctx.setAttributes(toAttributes(in));
ctx.setAttributeUpdatePolicy(Attributes.UpdatePolicy.REPLACE);
return ctx;
}

@PUT
@Path("/patients/{PatientID}")
@Path("/patients/{priorPatientID}")
@Consumes("application/dicom+json,application/json")
public void updatePatient(@PathParam("PatientID") IDWithIssuer patientID, InputStream in) {
public void updatePatient(
@PathParam("priorPatientID") IDWithIssuer priorPatientID,
@QueryParam("merge") @Pattern(regexp = "true|false") @DefaultValue("false") String merge,
InputStream in) {
logRequest();
ArchiveAEExtension arcAE = getArchiveAE();
PatientMgtContext ctx = patientService.createPatientMgtContextWEB(HttpServletRequestInfo.valueOf(request));
Attributes attrs = toAttributes(in);
ctx.setAttributes(attrs);
ctx.setAttributeUpdatePolicy(Attributes.UpdatePolicy.REPLACE);
IDWithIssuer bodyPatientID = ctx.getPatientID();
if (bodyPatientID == null)
PatientMgtContext ctx = patientMgtCtx(in);
IDWithIssuer targetPatientID = ctx.getPatientID();
if (targetPatientID == null)
throw new WebApplicationException(
errResponse("missing Patient ID in message body", Response.Status.BAD_REQUEST));

boolean mergePatients = Boolean.parseBoolean(merge);
boolean patientMatch = priorPatientID.equals(targetPatientID);
if (patientMatch && mergePatients)
throw new WebApplicationException(
errResponse("Circular Merge of Patients not allowed.", Response.Status.BAD_REQUEST));

RSOperation rsOp = RSOperation.CreatePatient;
String msgType = "ADT^A28^ADT_A05";
try {
boolean patientMatch = patientID.equals(bodyPatientID);
RSOperation rsOp = RSOperation.CreatePatient;
String msgType = "ADT^A28^ADT_A05";
if (patientMatch) {
patientService.updatePatient(ctx);
if (ctx.getEventActionCode().equals(AuditMessages.EventActionCode.Update)) {
rsOp = RSOperation.UpdatePatient;
msgType = "ADT^A31^ADT_A05";
}
}
else {
ctx.setPreviousAttributes(patientID.exportPatientIDWithIssuer(null));
patientService.changePatientID(ctx);
rsOp = RSOperation.ChangePatientID;
msgType = "ADT^A47^ADT_A30";
} else {
ctx.setPreviousAttributes(priorPatientID.exportPatientIDWithIssuer(null));
if (mergePatients) {
msgType = "ADT^A40^ADT_A39";
rsOp = RSOperation.MergePatient;
patientService.mergePatient(ctx);
} else {
msgType = "ADT^A47^ADT_A30";
rsOp = RSOperation.ChangePatientID;
patientService.changePatientID(ctx);
}
}

if (ctx.getEventActionCode().equals(AuditMessages.EventActionCode.Read))
return;

rsForward.forward(rsOp, arcAE, attrs, request);
rsForward.forward(rsOp, arcAE, ctx.getAttributes(), request);
rsHL7Sender.sendHL7Message(msgType, ctx);
} catch (PatientTrackingNotAllowedException | CircularPatientMergeException e) {
throw new WebApplicationException(
Expand Down
28 changes: 20 additions & 8 deletions dcm4chee-arc-ui2/src/swagger/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,6 @@
"200": {
"$ref": "#/components/responses/PatientID"
},
"400": {
"description": "Patient ID in request body"
},
"404": {
"description": "There is no Archive AE with the specified Title."
},
Expand Down Expand Up @@ -6774,7 +6771,7 @@
"tags": [
"PAM-RS"
],
"summary": "Update Patient in external archive",
"summary": "Update, Merge or Change Patient ID of Patient in external archive",
"operationId": "UpdatePatientExternal",
"parameters": [
{
Expand All @@ -6785,6 +6782,9 @@
},
{
"$ref": "#/components/parameters/queue"
},
{
"$ref": "#/components/parameters/merge"
}
],
"requestBody": {
Expand All @@ -6798,7 +6798,7 @@
"description": "Message accepted by Receiving HL7 Application"
},
"400": {
"description": "JSON request body was not well formed."
"description": "JSON request body was not well formed or Circular merge of patients not allowed."
},
"404": {
"description": "HL7 Application or External HL7 Application not configured"
Expand Down Expand Up @@ -8922,14 +8922,17 @@
"tags": [
"PAM-RS"
],
"summary": "Update or Create patient",
"operationId": "UpdateOrCreatePatient",
"summary": "Update, Create, Merge or Change Patient ID of patient",
"operationId": "UpdatePatient",
"parameters": [
{
"$ref": "#/components/parameters/archiveAETPathParam"
},
{
"$ref": "#/components/parameters/patientPathParam"
},
{
"$ref": "#/components/parameters/merge"
}
],
"requestBody": {
Expand All @@ -8940,7 +8943,7 @@
"description": "successful operation"
},
"400": {
"description": "Missing Patient ID in request body"
"description": "Missing Patient ID in request body or Circular Merge of Patients not allowed."
},
"404": {
"description": "There is no Archive AE with the specified Title."
Expand Down Expand Up @@ -13938,6 +13941,15 @@
"schema": {
"type": "boolean"
}
},
"merge": {
"name": "merge",
"in": "query",
"description": "Merge Patient",
"schema": {
"type": "boolean",
"default": false
}
}
},
"responses": {
Expand Down

0 comments on commit e374091

Please sign in to comment.