001package org.hl7.fhir.r4.utils; 002 003import java.io.File; 004import java.io.FileInputStream; 005import java.io.IOException; 006import java.net.URISyntaxException; 007import java.util.UUID; 008import java.util.zip.ZipEntry; 009import java.util.zip.ZipInputStream; 010 011import org.hl7.fhir.r4.formats.IParser; 012import org.hl7.fhir.r4.formats.JsonParser; 013import org.hl7.fhir.r4.model.Bundle; 014import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; 015import org.hl7.fhir.r4.model.Bundle.BundleType; 016import org.hl7.fhir.r4.model.Bundle.HTTPVerb; 017import org.hl7.fhir.r4.model.Resource; 018import org.hl7.fhir.r4.utils.client.FHIRToolingClient; 019import org.hl7.fhir.exceptions.FHIRException; 020import org.hl7.fhir.utilities.Utilities; 021 022public class BatchLoader { 023 024 public static void main(String[] args) throws IOException, Exception { 025 if (args.length < 4) { 026 System.out.println("Batch uploader takes 4 parameters in order: server base url, file/folder to upload, xml/json, and batch size"); 027 } else { 028 String server = args[0]; 029 String file = args[1]; 030 IParser p = new JsonParser(); // args[2].equals("json") ? new JsonParser() : new XmlParser(); 031 int size = Integer.parseInt(args[3]); 032 size = 500; 033 if (file.endsWith(".xml")) { 034 throw new FHIRException("Unimplemented file type "+file); 035 } else if (file.endsWith(".json")) { 036 throw new FHIRException("Unimplemented file type "+file); 037 } else if (file.endsWith(".zip")) { 038 LoadZipFile(server, file, p, size, 0, -1); 039 } else if (new File(file).isDirectory()) { 040 LoadDirectory(server, file, p, size); 041 } else 042 throw new FHIRException("Unknown file type "+file); 043 } 044 } 045 046 private static void LoadDirectory(String server, String file, IParser p, int size) throws IOException, Exception { 047// LoadZipFile(server, Utilities.path(file, "Patient.json.zip"), p, size, 1000, -1); 048// LoadZipFile(server, Utilities.path(file, "Binary.json.zip"), p, size, 0, -1); 049// LoadZipFile(server, Utilities.path(file, "DocumentReference.json.zip"), p, size, 0, -1); 050// LoadZipFile(server, Utilities.path(file, "Encounter.json.zip"), p, size, 0, -1); 051// LoadZipFile(server, Utilities.path(file, "Organization.json.zip"), p, size, 0, -1); 052// LoadZipFile(server, Utilities.path(file, "Procedure.json.zip"), p, size, 0, -1); 053// LoadZipFile(server, Utilities.path(file, "AllergyIntolerance.json.zip"), p, size, 1500, -1); 054// LoadZipFile(server, Utilities.path(file, "Condition.json.zip"), p, size, 0, -1); 055 LoadZipFile(server, Utilities.path(file, "Immunization.json.zip"), p, size, 0, -1); 056// LoadZipFile(server, Utilities.path(file, "MedicationStatement.json.zip"), p, size, 0, -1); 057// LoadZipFile(server, Utilities.path(file, "Observation-res.json.zip"), p, size, 0, -1); 058// LoadZipFile(server, Utilities.path(file, "Observation-sh.json.zip"), p, size, 0, -1); 059// LoadZipFile(server, Utilities.path(file, "Observation-vs.json.zip"), p, size, 0, -1); 060// LoadZipFile(server, Utilities.path(file, "Observation-gen.json.zip"), p, size, 0, -1); 061// LoadZipFile(server, Utilities.path(file, "List.json.zip"), p, size, 6500, -1); 062// LoadZipFile(server, Utilities.path(file, "List-res.json.zip"), p, size, 0, -1); 063// LoadZipFile(server, Utilities.path(file, "List-vs.json.zip"), p, size, 0, -1); 064 } 065 066 067 private static void LoadZipFile(String server, String file, IParser p, int size, int start, int end) throws IOException, Exception { 068 System.out.println("Load Zip file "+file); 069 Bundle b = new Bundle(); 070 b.setType(BundleType.COLLECTION); 071 b.setId(UUID.randomUUID().toString().toLowerCase()); 072 ZipInputStream zip = new ZipInputStream(new FileInputStream(file)); 073 ZipEntry entry; 074 while((entry = zip.getNextEntry())!=null) 075 { 076 try { 077 Resource r = p.parse(zip); 078 b.addEntry().setResource(r); 079 } catch (Exception e) { 080 throw new Exception("Error parsing "+entry.getName()+": "+e.getMessage(), e); 081 } 082 } 083 loadBundle(server, b, size, start, end); 084 } 085 086 087 private static int loadBundle(String server, Bundle b, int size, int start, int end) throws URISyntaxException { 088 System.out.println("Post to "+server+". size = "+Integer.toString(size)+", start = "+Integer.toString(start)+", total = "+Integer.toString(b.getEntry().size())); 089 FHIRToolingClient client = new FHIRToolingClient(server); 090 int c = start; 091 if (end == -1) 092 end = b.getEntry().size(); 093 while (c < end) { 094 Bundle bt = new Bundle(); 095 bt.setType(BundleType.BATCH); 096 bt.setId(UUID.randomUUID().toString().toLowerCase()); 097 for (int i = c; i < Math.min(b.getEntry().size(), c+size); i++) { 098 BundleEntryComponent be = bt.addEntry(); 099 be.setResource(b.getEntry().get(i).getResource()); 100 be.getRequest().setMethod(HTTPVerb.PUT); 101 be.getRequest().setUrl(be.getResource().getResourceType().toString()+"/"+be.getResource().getId()); 102 } 103 System.out.print(" posting.."); 104 long ms = System.currentTimeMillis(); 105 Bundle resp = client.transaction(bt); 106 107 for (int i = 0; i < resp.getEntry().size(); i++) { 108 BundleEntryComponent t = resp.getEntry().get(i); 109 if (!t.getResponse().getStatus().startsWith("2")) { 110 System.out.println("failed status at "+Integer.toString(i)+": "+t.getResponse().getStatus()); 111 return c+i; 112 } 113 } 114 c = c + size; 115 System.out.println(" ..done: "+Integer.toString(c)+". ("+Long.toString(System.currentTimeMillis()-ms)+" ms)"); 116 } 117 System.out.println(" done"); 118 return c; 119 } 120 121}