Class: Util::VSAC::VSACAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/util/vsac_api.rb

Constant Summary collapse

DEFAULT_PROGRAM =

The default program to use for get_program_details and get_program_release_names calls. This can be overriden by providing a :program in the config or by the single optional parameter for those methods.

"CMS eCQM"
TICKET_SERVICE_PARAM =

This is the value of the service parameter passed when getting a ticket. This never changes.

"http://umlsks.nlm.nih.gov"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ VSACAPI

Creates a new VSACAPI. If credentials were provided they are checked now. If no credentials are provided then the API can still be used for utility methods.

Options for the API are passed in as a hash.

  • config -



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
107
108
109
110
111
112
113
114
115
# File 'lib/util/vsac_api.rb', line 81

def initialize(options)
  # check that :config exists and has needed fields
  if options[:config].nil?
    raise VSACArgumentError.new("Required param :config is missing or empty.")
  else
    symbolized_config = options[:config].symbolize_keys
    if check_config symbolized_config
      @config = symbolized_config
    else
      raise VSACArgumentError.new("Required param :config is missing required URLs.")
    end
  end

  # if a ticket_granting_ticket was passed in, check it and raise errors if found
  # username and password will be ignored
  if !options[:ticket_granting_ticket].nil?
    provided_ticket_granting_ticket = options[:ticket_granting_ticket]
    if provided_ticket_granting_ticket[:ticket].nil? || provided_ticket_granting_ticket[:expires].nil?
      raise VSACArgumentError.new("Optional param :ticket_granting_ticket is missing :ticket or :expires")
    end

    # check if it has expired
    if Time.now > provided_ticket_granting_ticket[:expires]
      raise VSACTicketExpiredError.new
    end

    # ticket granting ticket looks good
    @ticket_granting_ticket = { ticket: provided_ticket_granting_ticket[:ticket],
      expires: provided_ticket_granting_ticket[:expires] }

  # if username and password were provided use them to get a ticket granting ticket
  elsif !options[:username].nil? && !options[:password].nil?
    @ticket_granting_ticket = get_ticket_granting_ticket(options[:username], options[:password])
  end
end

Instance Attribute Details

#ticket_granting_ticketObject (readonly)

The ticket granting that will be obtained if needed. Accessible so it may be stored in user session. Is a hash of the :ticket and time it :expires.



73
74
75
# File 'lib/util/vsac_api.rb', line 73

def ticket_granting_ticket
  @ticket_granting_ticket
end

Instance Method Details

#get_latest_profile_for_program(program = nil) ⇒ Object

Gets the latest profile for a program. This is a separate call from the program details call. It returns JSON with only the name of the latest profile and the timestamp of the request. ex:

{
  "name": "eCQM Update 2018-05-04",
  "requestTime": "2018-05-21 03:39:04 PM"
}

Optional parameter program is the program to request from the API. If it is not provided it will look for a :program in the config passed in during construction. If there is no :program in the config it will use the DEFAULT_PROGRAM constant for the program.

Returns the name of the latest profile for the given program.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/util/vsac_api.rb', line 187

def get_latest_profile_for_program(program = nil)
  # if no program was provided use the one in the config or default in constant
  if program.nil?
    program = @config.fetch(:program, DEFAULT_PROGRAM)
  end

  begin
    # parse json response and return it
    parsedResponse = JSON.parse(RestClient.get("#{@config[:utility_url]}/program/#{ERB::Util.url_encode(program)}/latest%20profile"))

    # As of 5/17/18 VSAC does not return 404 when an invalid profile is provided. It just doesnt fill the name
    # attribute in the 200 response. We need to check this.
    if !parsedResponse['name'].nil?
      return parsedResponse['name']
    else
      raise VSACProgramNotFoundError.new(program)
    end

  # keeping this rescue block in case the API is changed to return 404 for invalid profile
  rescue RestClient::ResourceNotFound
    raise VSACProgramNotFoundError.new(program)
  end
end

#get_profile_namesObject

Gets the list of profiles. This may be used without credentials.

Returns a list of profile names. These are kept in the order that VSAC provides them in.



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/util/vsac_api.rb', line 121

def get_profile_names
  profiles_response = RestClient.get("#{@config[:utility_url]}/profiles")
  profiles = []

  # parse xml response and get text content of each profile element
  doc = Nokogiri::XML(profiles_response)
  profile_list = doc.at_xpath("/ProfileList")
  profile_list.xpath("//profile").each do |profile|
    profiles << profile.text
  end

  return profiles
end

#get_program_details(program = nil) ⇒ Object

Gets the details for a program. This may be used without credentials.

Optional parameter program is the program to request from the API. If it is not provided it will look for a :program in the config passed in during construction. If there is no :program in the config it will use the DEFAULT_PROGRAM constant for the program.

Returns the JSON parsed response for program details.



160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/util/vsac_api.rb', line 160

def get_program_details(program = nil)
  # if no program was provided use the one in the config or default in constant
  if program.nil?
    program = @config.fetch(:program, DEFAULT_PROGRAM)
  end

  begin
    # parse json response and return it
    return JSON.parse(RestClient.get("#{@config[:utility_url]}/program/#{ERB::Util.url_encode(program)}"))
  rescue RestClient::ResourceNotFound
    raise VSACProgramNotFoundError.new(program)
  end
end

#get_program_namesObject

Gets the list of programs. This may be used without credentials.

Returns a list of program names. These are kept in the order that VSAC provides them in.



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/util/vsac_api.rb', line 139

def get_program_names
  programs_response = RestClient.get("#{@config[:utility_url]}/programs")
  program_names = []

  # parse json response and return the names of the programs
  programs_info = JSON.parse(programs_response)['Program']
  programs_info.each do |program|
    program_names << program['name']
  end

  return program_names
end

#get_program_release_names(program = nil) ⇒ Object

Gets the releases for a program. This may be used without credentials.

Optional parameter program is the program to request from the API. If it is not provided it will look for a :program in the config passed in during construction. If there is no :program in the config it will use the DEFAULT_PROGRAM constant for the program.

Returns a list of release names in a program. These are kept in the order that VSAC provides them in.



219
220
221
222
223
224
225
226
227
228
229
# File 'lib/util/vsac_api.rb', line 219

def get_program_release_names(program = nil)
  program_details = get_program_details(program)
  releases = []

  # pull just the release names out
  program_details['release'].each do |release|
    releases << release['name']
  end

  return releases
end

#get_valueset(oid, options = {}) ⇒ Object

Gets a valueset. This requires credentials.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/util/vsac_api.rb', line 234

def get_valueset(oid, options = {})
  # base parameter oid is always needed
  params = { id: oid }

  # release parameter, should be used moving forward
  if !options[:release].nil?
    params[:release] = options[:release]
  end

  # profile parameter, may be needed for getting draft value sets
  if !options[:profile].nil?
    params[:profile] = options[:profile]
    if !options[:include_draft].nil?
      params[:includeDraft] = if !!options[:include_draft] then 'yes' else 'no' end
    end
  else
    if !options[:include_draft].nil?
      raise VSACArgumentError.new("Option :include_draft requires :profile to be provided.")
    end
  end

  # version parameter, rarely used
  if !options[:version].nil?
    params[:version] = options[:version]
  end

  # get a new service ticket
  params[:ticket] = get_ticket

  # run request
  begin
    return RestClient.get("#{@config[:content_url]}/RetrieveMultipleValueSets", params: params)
  rescue RestClient::ResourceNotFound
    raise VSNotFoundError.new(oid)
  rescue RestClient::InternalServerError
    raise VSACError.new("Server error response from VSAC for (#{oid}).")
  end
end