Module: Inferno::Terminology::FHIRPackageManager

Defined in:
lib/inferno/terminology/fhir_package_manager.rb

Constant Summary collapse

REGISTRY_SERVER_URL =
'https://packages.fhir.org'.freeze
US_CORE_7_PACKAGE_URL =
'https://hl7.org/fhir/us/core/STU7/package.tgz'.freeze
VSAC_18_PACKAGE_URL =
'https://packages2.fhir.org/web//us.nlm.vsac-0.18.0.tgz'.freeze
REQUIRED_VSAC_VALUE_SET_URLS =
[
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.1.11.14914',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.877',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.102',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.103',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.2074.1.1.3',
  'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1240.3'
  # The ValueSets below are needed when building all of the terminology
  # rather than only the terminology for required bindings.
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.8',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.30',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.6',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.4',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.11.20.9.38',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.1066',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.1.11.10267',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1099.27',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1010.5',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1021.32',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.1',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.88.12.80.17',
  # 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1186.2'
].freeze

Class Method Summary collapse

Class Method Details

.encode_name(name) ⇒ Object



108
109
110
# File 'lib/inferno/terminology/fhir_package_manager.rb', line 108

def encode_name(name)
  Zlib.crc32(name)
end

.get_package(package, destination, desired_types = []) ⇒ Object

Get the FHIR Package from the registry.

e.g. get_package(‘hl7.fhir.us.core#3.1.1’)



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/inferno/terminology/fhir_package_manager.rb', line 48

def get_package(package, destination, desired_types = [])
  package_url = case package
                when 'hl7.fhir.us.core#7.0.0'
                  US_CORE_7_PACKAGE_URL
                when 'us.nlm.vsac#0.18.0'
                  VSAC_18_PACKAGE_URL
                else
                  package
                    .split('#')
                    .prepend(REGISTRY_SERVER_URL)
                    .join('/')
                end

  tar_file_name = "tmp/#{package.split('#').join('-')}.tgz"

  File.open(tar_file_name, 'w') do |output_file|
    output_file.binmode
    block = proc do |response|
      if ['301', '302', '307'].include? response.code
        RestClient::Request.execute(method: :get, url: response.header[:location], block_response: block)
      else
        response.read_body do |chunk|
          output_file.write chunk
        end
      end
    end

    puts "Downloading #{package_url}"
    RestClient::Request.execute(method: :get, url: package_url, block_response: block)
  end

  tar = Gem::Package::TarReader.new(Zlib::GzipReader.open("tmp/#{package.split('#').join('-')}.tgz"))

  path = File.join destination.split('/')
  FileUtils.mkdir_p(path)

  tar.each do |entry|
    next if entry.directory?

    next unless entry.full_name.start_with? 'package/'

    file_name = entry.full_name.split('/').last
    next if desired_types.present? && !file_name.start_with?(*desired_types)

    resource = JSON.parse(entry.read) if file_name.end_with? '.json'
    next unless resource&.[]('url')

    next if package.start_with?('us.nlm.vsac') && !REQUIRED_VSAC_VALUE_SET_URLS.include?(resource['url'])

    encoded_name = "#{encode_name(resource['url'])}.json"
    encoded_file_name = File.join(path, encoded_name)
    if File.exist?(encoded_file_name) && !resource['url'] == JSON.parse(File.read(encoded_file_name))['url']
      raise FileExistsException, "#{encoded_name} already exists for #{resource['url']}"
    end

    File.write(encoded_file_name, resource.to_json)
  end
  File.delete(tar_file_name)
end