001package org.hl7.fhir.dstu2.utils; 002 003/*- 004 * #%L 005 * org.hl7.fhir.dstu2 006 * %% 007 * Copyright (C) 2014 - 2019 Health Level 7 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023 024import java.io.File; 025import java.io.FileInputStream; 026import java.io.IOException; 027import java.net.URISyntaxException; 028import java.util.UUID; 029import java.util.zip.ZipEntry; 030import java.util.zip.ZipInputStream; 031 032import org.hl7.fhir.dstu2.formats.IParser; 033import org.hl7.fhir.dstu2.formats.JsonParser; 034import org.hl7.fhir.dstu2.model.Bundle; 035import org.hl7.fhir.dstu2.model.Bundle.BundleEntryComponent; 036import org.hl7.fhir.dstu2.model.Bundle.BundleType; 037import org.hl7.fhir.dstu2.model.Bundle.HTTPVerb; 038import org.hl7.fhir.dstu2.model.Resource; 039import org.hl7.fhir.dstu2.utils.client.FHIRToolingClient; 040import org.hl7.fhir.exceptions.FHIRException; 041import org.hl7.fhir.utilities.Utilities; 042 043public class BatchLoader { 044 045 public static void main(String[] args) throws IOException, Exception { 046 if (args.length < 4) { 047 System.out.println("Batch uploader takes 4 parameters in order: server base url, file/folder to upload, xml/json, and batch size"); 048 } else { 049 String server = args[0]; 050 String file = args[1]; 051 IParser p = new JsonParser(); // args[2].equals("json") ? new JsonParser() : new XmlParser(); 052 int size = Integer.parseInt(args[3]); 053 size = 500; 054 if (file.endsWith(".xml")) { 055 throw new FHIRException("Unimplemented file type "+file); 056 } else if (file.endsWith(".json")) { 057 throw new FHIRException("Unimplemented file type "+file); 058 } else if (file.endsWith(".zip")) { 059 LoadZipFile(server, file, p, size, 0, -1); 060 } else if (new File(file).isDirectory()) { 061 LoadDirectory(server, file, p, size); 062 } else 063 throw new FHIRException("Unknown file type "+file); 064 } 065 } 066 067 private static void LoadDirectory(String server, String file, IParser p, int size) throws IOException, Exception { 068// LoadZipFile(server, Utilities.path(file, "Patient.json.zip"), p, size, 1000, -1); 069// LoadZipFile(server, Utilities.path(file, "Binary.json.zip"), p, size, 0, -1); 070// LoadZipFile(server, Utilities.path(file, "DocumentReference.json.zip"), p, size, 0, -1); 071// LoadZipFile(server, Utilities.path(file, "Encounter.json.zip"), p, size, 0, -1); 072// LoadZipFile(server, Utilities.path(file, "Organization.json.zip"), p, size, 0, -1); 073// LoadZipFile(server, Utilities.path(file, "Procedure.json.zip"), p, size, 0, -1); 074// LoadZipFile(server, Utilities.path(file, "AllergyIntolerance.json.zip"), p, size, 1500, -1); 075// LoadZipFile(server, Utilities.path(file, "Condition.json.zip"), p, size, 0, -1); 076 LoadZipFile(server, Utilities.path(file, "Immunization.json.zip"), p, size, 0, -1); 077// LoadZipFile(server, Utilities.path(file, "MedicationStatement.json.zip"), p, size, 0, -1); 078// LoadZipFile(server, Utilities.path(file, "Observation-res.json.zip"), p, size, 0, -1); 079// LoadZipFile(server, Utilities.path(file, "Observation-sh.json.zip"), p, size, 0, -1); 080// LoadZipFile(server, Utilities.path(file, "Observation-vs.json.zip"), p, size, 0, -1); 081// LoadZipFile(server, Utilities.path(file, "Observation-gen.json.zip"), p, size, 0, -1); 082// LoadZipFile(server, Utilities.path(file, "List.json.zip"), p, size, 6500, -1); 083// LoadZipFile(server, Utilities.path(file, "List-res.json.zip"), p, size, 0, -1); 084// LoadZipFile(server, Utilities.path(file, "List-vs.json.zip"), p, size, 0, -1); 085 } 086 087 088 private static void LoadZipFile(String server, String file, IParser p, int size, int start, int end) throws IOException, Exception { 089 System.out.println("Load Zip file "+file); 090 Bundle b = new Bundle(); 091 b.setType(BundleType.COLLECTION); 092 b.setId(UUID.randomUUID().toString().toLowerCase()); 093 ZipInputStream zip = new ZipInputStream(new FileInputStream(file)); 094 ZipEntry entry; 095 while((entry = zip.getNextEntry())!=null) 096 { 097 try { 098 Resource r = p.parse(zip); 099 b.addEntry().setResource(r); 100 } catch (Exception e) { 101 throw new Exception("Error parsing "+entry.getName()+": "+e.getMessage(), e); 102 } 103 } 104 loadBundle(server, b, size, start, end); 105 } 106 107 108 private static int loadBundle(String server, Bundle b, int size, int start, int end) throws URISyntaxException { 109 System.out.println("Post to "+server+". size = "+Integer.toString(size)+", start = "+Integer.toString(start)+", total = "+Integer.toString(b.getEntry().size())); 110 FHIRToolingClient client = new FHIRToolingClient(server); 111 int c = start; 112 if (end == -1) 113 end = b.getEntry().size(); 114 while (c < end) { 115 Bundle bt = new Bundle(); 116 bt.setType(BundleType.BATCH); 117 bt.setId(UUID.randomUUID().toString().toLowerCase()); 118 for (int i = c; i < Math.min(b.getEntry().size(), c+size); i++) { 119 BundleEntryComponent be = bt.addEntry(); 120 be.setResource(b.getEntry().get(i).getResource()); 121 be.getRequest().setMethod(HTTPVerb.PUT); 122 be.getRequest().setUrl(be.getResource().getResourceType().toString()+"/"+be.getResource().getId()); 123 } 124 System.out.print(" posting.."); 125 long ms = System.currentTimeMillis(); 126 Bundle resp = client.transaction(bt); 127 128 for (int i = 0; i < resp.getEntry().size(); i++) { 129 BundleEntryComponent t = resp.getEntry().get(i); 130 if (!t.getResponse().getStatus().startsWith("2")) { 131 System.out.println("failed status at "+Integer.toString(i)+": "+t.getResponse().getStatus()); 132 return c+i; 133 } 134 } 135 c = c + size; 136 System.out.println(" ..done: "+Integer.toString(c)+". ("+Long.toString(System.currentTimeMillis()-ms)+" ms)"); 137 } 138 System.out.println(" done"); 139 return c; 140 } 141 142}