001package org.hl7.fhir.validation.ipa; 002 003import java.io.ByteArrayInputStream; 004import java.util.ArrayList; 005import java.util.List; 006import java.util.Map; 007 008import org.hl7.fhir.r5.elementmodel.Element; 009import org.hl7.fhir.r5.elementmodel.JsonParser; 010import org.hl7.fhir.utilities.SimpleHTTPClient; 011import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult; 012import org.hl7.fhir.utilities.validation.ValidationMessage; 013import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 014import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; 015import org.hl7.fhir.utilities.validation.ValidationMessage.Source; 016import org.hl7.fhir.validation.instance.InstanceValidator; 017 018/** 019 * You give this validator three parameters: 020 * URL of server 021 * access token for the server (most be already logged in) 022 * patient ID - the patient ID that was authorised by the log in 023 * 024 * @author grahamegrieve 025 * 026 */ 027public class IPAValidator { 028 029 public class ValidationNode { 030 031 public ValidationNode(String string) { 032 // TODO Auto-generated constructor stub 033 } 034 035 public List<ValidationMessage> getIssues() { 036 // TODO Auto-generated method stub 037 return null; 038 } 039 040 public String getName() { 041 // TODO Auto-generated method stub 042 return null; 043 } 044 045 } 046 047 private String address; 048 private String token; 049 private String urn; 050 private InstanceValidator validator; 051 052 public IPAValidator(String address, String token, String urn, InstanceValidator validator) { 053 super(); 054 this.address = address; 055 this.token = token; 056 this.urn = urn; 057 this.validator = validator; 058 } 059 060 public String getAddress() { 061 return address; 062 } 063 064 public void setAddress(String address) { 065 this.address = address; 066 } 067 068 public String getToken() { 069 return token; 070 } 071 072 public void setToken(String token) { 073 this.token = token; 074 } 075 076 public String getUrn() { 077 return urn; 078 } 079 080 public void setUrn(String urn) { 081 this.urn = urn; 082 } 083 084 public InstanceValidator getValidator() { 085 return validator; 086 } 087 088 public void setValidator(InstanceValidator validator) { 089 this.validator = validator; 090 } 091 092 public void validate() { 093 List<Element> patients = searchPatients(); 094 if (patients.size() > 0) { 095 096 // validate all resources and links 097 // validate search parameters 098 // check self links 099 100// AllergyIntolerance patient patient+clinical-status 101// Condition patient patient+category, patient+clinical-status, patient+code, patient+onset-date, patient+category+clinical_status 102// DocumentReference _id, patient, patient+category, patient+type patient+category+date, patient+status, patient+type+period 103// Immunization patient patient+date, patient+status 104// MedicationRequest patient patient+intent, patient+intent+authoredon, patient+intent+status 105// MedicationStatement subject subject+status 106// Observation patient+category, patient+code, patient+category+date patient+category+status, patient+code+date 107// Patient _id, identifier birthdate, family, gender, given, name, family+gender, birthdate+family, birthdate+name, gender+name 108 109 } 110 111 112 113 } 114 115 private List<Element> searchPatients() { 116 ValidationNode vn = new ValidationNode("Patient Search"); 117 log("Searching Patients"); 118 Element bundle = makeRequest(vn, "/Patient"); 119 List<Element> list = new ArrayList<>(); 120 if (bundle != null) { 121 checkSelfLink(vn, bundle, null); 122 List<Element> entries = bundle.getChildren("entry"); 123 int i = 0; 124 for (Element entry : entries) { 125 Element resource = entry.getNamedChild("resource"); 126 if (resource != null && resource.fhirType().equals("Patient")) { 127 validator.validate(this, vn.getIssues(), "Bundle.entry["+i+"].resource", resource, "http://hl7.org/fhir/uv/ipa/StructureDefinition/ipa-patient"); 128 list.add(resource); 129 } 130 } 131 } 132 if (list.size() > 1) { 133 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "patient.search", 134 "Multiple Patients found; check that this is an expected outcome", 135 IssueSeverity.WARNING)); 136 } else if (list.size() == 0) { 137 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "patient.search", 138 "No Patients found, unable to continue", 139 IssueSeverity.ERROR)); 140 } 141 return list; 142 } 143 144 private void checkSelfLink(ValidationNode vn, Element bundle, Map<String, String> params) { 145 // we check that there's a self link 146 Element sl = null; 147 for (Element e : bundle.getChildren("link")) { 148 if ("self".equals(e.getNamedChildValue("relation"))) { 149 sl = e.getNamedChild("url"); 150 } 151 } 152 if (sl == null) { 153 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, vn.getName(), 154 "Self link not found in search result", 155 IssueSeverity.ERROR)); 156 } else if (params != null) { 157 // we check that all the provided params are in the self link 158 } 159 } 160 161 private Element makeRequest(ValidationNode vn, String url) { 162 try { 163 SimpleHTTPClient http = new SimpleHTTPClient(); 164 HTTPResult result = http.get(url, "application/fhir+json"); 165 if (result.getCode() >= 300) { 166 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request", 167 "HTTP Return code is "+result.getCode()+" "+result.getMessage(), 168 IssueSeverity.FATAL)); 169 return null; 170 } else if (result.getContent() == null || result.getContent().length == 0) { 171 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request", 172 "No Content Returned", 173 IssueSeverity.FATAL)); 174 return null; 175 } else { 176 return new JsonParser(validator.getContext()).parse(new ByteArrayInputStream(result.getContent())).get(0).getElement(); 177 } 178 } catch (Exception e) { 179 vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request", e.getMessage(), 180 IssueSeverity.FATAL)); 181 return null; 182 } 183 184 } 185 186 private void log(String msg) { 187 System.out.println(msg); 188 } 189}