001package org.hl7.fhir.r5.test.utils;
002
003import java.io.File;
004import java.io.IOException;
005import java.io.InputStream;
006import java.util.HashMap;
007import java.util.Locale;
008import java.util.Map;
009
010import lombok.extern.slf4j.Slf4j;
011import org.fhir.ucum.UcumEssenceService;
012import org.hl7.fhir.r5.Constants;
013import org.hl7.fhir.r5.context.IContextResourceLoader;
014import org.hl7.fhir.r5.context.IWorkerContext;
015import org.hl7.fhir.r5.context.SimpleWorkerContext;
016import org.hl7.fhir.r5.model.Parameters;
017import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
018import org.hl7.fhir.utilities.Utilities;
019import org.hl7.fhir.utilities.VersionUtilities;
020import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
021import org.hl7.fhir.utilities.npm.BasePackageCacheManager.InputStreamWithSrc;
022import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
023import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager.IPackageProvider;
024import org.hl7.fhir.utilities.npm.NpmPackage;
025import org.hl7.fhir.utilities.tests.BaseTestingUtilities;
026import org.hl7.fhir.utilities.tests.TestConfig;
027
028@Slf4j
029public class TestingUtilities extends BaseTestingUtilities {
030
031  public static class PackageProvider implements IPackageProvider {
032
033    @Override
034    public boolean handlesPackage(String id, String version) {
035      return id.equals("hl7.fhir.r5.core");
036    }
037
038    @Override
039    public InputStreamWithSrc provide(String id, String version) throws IOException {
040      return new InputStreamWithSrc(TestingUtilities.loadR5CorePackageSource(), "Test Case Repository", "5.0.0");
041    }
042
043  }
044
045  static public Map<String, SimpleWorkerContext> fcontexts;
046
047  final static public String DEFAULT_CONTEXT_VERSION = "5.0.0";
048
049  /** Get an existing instantiation of a WorkerContext if available
050   *
051   * This uses the DEFAULT_CONTEXT_VERSION
052   * */
053  public static SimpleWorkerContext getSharedWorkerContext() {
054    return getSharedWorkerContext(DEFAULT_CONTEXT_VERSION);
055  }
056
057  /**
058   * Get an existing instantiation of a WorkerContext if available
059   *
060   * @param version FHIR Version to get context for
061   * @return
062   */
063  public static SimpleWorkerContext getSharedWorkerContext(String version) {
064    if (!Utilities.existsInList(version, "1.0.2", "3.0.1", "4.0.1", "4.3.0", "5.0.0")) {
065      throw new Error("illegal version: "+version);
066      
067    }
068    
069    String v = VersionUtilities.getMajMin(version);
070    if (fcontexts == null) {
071      fcontexts = new HashMap<>();
072    }
073    if (!fcontexts.containsKey(v)) {
074      SimpleWorkerContext fcontext = getWorkerContext(version);
075        fcontexts.put(v, fcontext);
076    }
077    return fcontexts.get(v);
078  }
079
080  public static SimpleWorkerContext getWorkerContext(String version) {
081
082    FilesystemPackageCacheManager pcm;
083    try {
084      pcm = new FilesystemPackageCacheManager.Builder().build();
085      SimpleWorkerContext fcontext = null;
086      if (VersionUtilities.isR5Ver(version)) {
087        // for purposes of stability, the R5 core package comes from the test case repository
088        fcontext = getWorkerContext(loadR5CorePackage());
089      } else {
090        fcontext = getWorkerContext(pcm.loadPackage(VersionUtilities.packageForVersion(version), version));
091      }
092      fcontext.setUcumService(new UcumEssenceService(TestingUtilities.loadTestResourceStream("ucum", "ucum-essence.xml")));
093      fcontext.setExpansionParameters(new Parameters());
094      if (!fcontext.hasPackage("hl7.terminology.r5", null)) {
095        NpmPackage utg = pcm.loadPackage("hl7.terminology.r5");
096        log.info("Loading THO: "+utg.name()+"#"+utg.version());
097        fcontext.loadFromPackage(utg, new TestPackageLoader(Utilities.stringSet("CodeSystem", "ValueSet")));
098      } 
099      if (!fcontext.hasPackage("hl7.fhir.uv.extensions", null)) {
100        NpmPackage ext = pcm.loadPackage("hl7.fhir.uv.extensions", Constants.EXTENSIONS_WORKING_VERSION);
101        log.info("Loading Extensions: "+ext.name()+"#"+ext.version());
102        fcontext.loadFromPackage(ext, new TestPackageLoader(Utilities.stringSet("CodeSystem", "ValueSet", "StructureDefinition")));
103      } 
104      return fcontext;
105    } catch (Exception e) {
106      e.printStackTrace();
107      throw new Error(e);
108    }
109  }
110
111  public static NpmPackage loadR5CorePackage() throws IOException {
112    return NpmPackage.fromPackage(loadR5CorePackageSource());
113  }
114
115  private static InputStream loadR5CorePackageSource() throws IOException {
116    return TestingUtilities.loadTestResourceStream("r5", "packages", "hl7.fhir.r5.core.tgz");
117  }
118
119  public static String getTerminologyCacheDirectory() {
120    return TestConfig.getInstance().getTxCacheDirectory("org.hl7.fhir.r5");
121  }
122
123  public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage) throws Exception {
124    SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).withUserAgent(TestConstants.USER_AGENT)
125        .withTerminologyCachePath(getTerminologyCacheDirectory()).fromPackage(npmPackage);
126    TerminologyCache.setCacheErrors(true);
127    return swc;
128  }
129
130  public static SimpleWorkerContext getWorkerContext(NpmPackage npmPackage, IContextResourceLoader loader) throws Exception {
131    SimpleWorkerContext swc = new SimpleWorkerContext.SimpleWorkerContextBuilder().withAllowLoadingDuplicates(true).withUserAgent(TestConstants.USER_AGENT)
132        .withTerminologyCachePath(getTerminologyCacheDirectory()).fromPackage(npmPackage, loader, true);
133    TerminologyCache.setCacheErrors(true);
134    return swc;
135  }
136
137  static public String fixedpath;
138  static public String contentpath;
139
140  public static String home() throws IOException {
141    if (fixedpath != null)
142      return fixedpath;
143    String s = System.getenv("FHIR_HOME");
144    if (!Utilities.noString(s))
145      return s;
146    s = "C:\\work\\org.hl7.fhir\\build";
147    // #TODO - what should we do with this?
148    s = "/Users/jamesagnew/git/fhir";
149    if (ManagedFileAccess.file(s).exists())
150      return s;
151    throw new Error("FHIR Home directory not configured");
152  }
153
154
155  public static String content() throws IOException {
156    if (contentpath != null)
157      return contentpath;
158    String s = "R:\\fhir\\publish";
159    if (ManagedFileAccess.file(s).exists())
160      return s;
161    return Utilities.path(home(), "publish");
162  }
163
164  // diretory that contains all the US implementation guides
165  public static String us() throws IOException {
166    if (fixedpath != null)
167      return fixedpath;
168    String s = System.getenv("FHIR_HOME");
169    if (!Utilities.noString(s))
170      return s;
171    s = "C:\\work\\org.hl7.fhir.us";
172    if (ManagedFileAccess.file(s).exists())
173      return s;
174    throw new Error("FHIR US directory not configured");
175  }
176
177  public static void injectCorePackageLoader() {
178    FilesystemPackageCacheManager.setPackageProvider(new TestingUtilities.PackageProvider());    
179  }
180
181  public static boolean runningAsSurefire() {
182    return "true".equals(System.getProperty("runningAsSurefire") != null ? System.getProperty("runningAsSurefire").toLowerCase(Locale.ENGLISH) : "");
183  }
184}