Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exploding va_rx gem into vets-api -- with minor refactor #88

Merged
merged 8 commits into from
Sep 13, 2016
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ Metrics/ClassLength:

Metrics/AbcSize:
Max: 30

# excluding these because get_session implies HTTP GET, and is useful
Style/AccessorMethodName:
Exclude:
- 'lib/rx/**/*'
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ gem 'json-schema'
gem 'active_model_serializers', '~> 0.10.0'
gem 'will_paginate'
gem 'va-api-common', git: 'https://github.com/department-of-veterans-affairs/va-api-common', branch: 'master'
gem 'va_rx', git: 'https://github.com/department-of-veterans-affairs/va_rx.git', branch: 'master'
gem 'va_healthcare_messaging',
git: 'https://github.com/department-of-veterans-affairs/va_healthcare_messaging.git', branch: 'master'
gem 'faraday'
Expand Down
12 changes: 0 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ GIT
multi_json (~> 1.0)
virtus

GIT
remote: https://github.com/department-of-veterans-affairs/va_rx.git
revision: 73201c9b11306ab7a2b369570c03ef4aa80755a2
branch: master
specs:
va_rx (0.1.0)
activemodel (>= 4.1, < 6)
faraday
multi_json (~> 1.0)
virtus

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -362,7 +351,6 @@ DEPENDENCIES
tzinfo-data
va-api-common!
va_healthcare_messaging!
va_rx!
vcr
virtus
web-console (~> 2.0)
Expand Down
12 changes: 7 additions & 5 deletions app/controllers/rx_controller.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# frozen_string_literal: true
require_dependency 'rx/client'

class RxController < ApplicationController
# FIXME: when ID.me is working we need to use it here, but for now skip
# and just rely on the http basic authentication.
skip_before_action :authenticate

VARX_ENFORCE_SSL = Rails.env.production?
MHV_CONFIG = VARx::Configuration.new(
RX_ENFORCE_SSL = Rails.env.production?
MHV_CONFIG = Rx::Configuration.new(
host: ENV['MHV_HOST'],
app_token: ENV['MHV_APP_TOKEN'],
enforce_ssl: VARX_ENFORCE_SSL
enforce_ssl: RX_ENFORCE_SSL
).freeze

include ActionController::Serialization
Expand All @@ -26,15 +28,15 @@ class RxController < ApplicationController
# end
#
# def render_error(e, status_code: 500)
# if e.is_a? VARx::Error::ClientResponse
# if e.is_a? Rx::Error::ClientResponse
# render json: { errors: [e.as_json] }, status: status_code
# else
# render json: { errors: [errors_hash(e, status_code)] }, status: status_code
# end
# end

def client
@client ||= VARx::Client.new(config: MHV_CONFIG, session: { user_id: ENV['MHV_USER_ID'] })
@client ||= Rx::Client.new(config: MHV_CONFIG, session: { user_id: ENV['MHV_USER_ID'] })
end

def authenticate_client
Expand Down
30 changes: 30 additions & 0 deletions app/models/prescription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'common/models/base'
# Prescription model
# Reference: https://github.com/department-of-veterans-affairs/prescriptions-team/blob/master/API/sample_mvh_api_calls
class Prescription < Common::Base
attribute :prescription_id, Integer
attribute :refill_status, String
attribute :refill_submit_date, Common::UTCTime
attribute :refill_date, Common::UTCTime
attribute :refill_remaining, Integer
attribute :facility_name, String
attribute :ordered_date, Common::UTCTime
attribute :quantity, Integer
attribute :expiration_date, Common::UTCTime
attribute :prescription_number, String
attribute :prescription_name, String
attribute :dispensed_date, Common::UTCTime
attribute :station_number, String
attribute :is_refillable, Boolean
attribute :is_trackable, Boolean

alias refillable? is_refillable
alias trackable? is_trackable

def <=>(other)
return -1 if prescription_id < other.prescription_id
return 1 if prescription_id > other.prescription_id
0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be shortened to prescription_id <=> other.prescription_id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe... (it should) let me test that out really quick -- will make similar change for tracking if its the case.

end
end
20 changes: 20 additions & 0 deletions app/models/tracking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true
require 'common/models/base'
# Tracking Model
class Tracking < Common::Base
attribute :prescription_id, Integer
attribute :prescription_name, String
attribute :prescription_number, String
attribute :facility_name, String
attribute :rx_info_phone_number, String
attribute :ndc_number, String
attribute :shipped_date, Common::UTCTime
attribute :delivery_service, String
attribute :tracking_number, String

def <=>(other)
return -1 if shipped_date < other.shipped_date
return 1 if shipped_date > other.shipped_date
0
end
end
30 changes: 30 additions & 0 deletions lib/common/client/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true
module Common
module Client
# Configuration class used to setup the environment used by client
class Configuration
OPEN_TIMEOUT = 15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment with units. Seconds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, i can do that -- ping me when you're done reviewing.

READ_TIMEOUT = 15

attr_reader :app_token, :open_timeout, :read_timeout

def initialize(host:, app_token:, open_timeout: OPEN_TIMEOUT, read_timeout: READ_TIMEOUT, enforce_ssl: true)
@app_token = app_token
@host = URI.parse(host)
@open_timeout = open_timeout
@read_timeout = read_timeout
assert_ssl if enforce_ssl
end

def base_path
raise NotImplementedError, 'you must provide a base_path.'
end

private

def assert_ssl
raise ArgumentError, 'host must use ssl' unless @host.is_a?(URI::HTTPS)
end
end
end
end
72 changes: 72 additions & 0 deletions lib/common/client/errors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true
require 'faraday/error'

# FIXME: this needs to be adapted to use va-api-common style errors
module Common
module Client
# The error class defines the various error types that the client can encounter
module Errors
class Error < StandardError; end

class NotAuthenticated < Error; end
class Client < Error; end
class Serialization < Error; end
class RequestTimeout < ::Faraday::Error::TimeoutError; end
class ConnectionFailed < ::Faraday::Error::ConnectionFailed; end

# This error class is for handling the various error types identified in error_codes.rb
class ClientResponse < Error
def initialize(status_code, parsed_json)
@status_code = status_code
@parsed_json = parsed_json
end

def error
return @cause unless @cause.nil?
self
end

def major
@status_code
end

def minor
@parsed_json['errorCode']
end

def message
@parsed_json['message']
end

def developer_message
@parsed_json['developerMessage']
end

def as_json
return debug_hash if defined?(Rails) && (Rails.env.development? || Rails.env.test?)
base_json
end

delegate :to_json, to: :as_json

def to_s
to_json
end

private

def base_json
{ major: major, minor: minor, message: message }
end

def cause_to_hash
@cause.nil? ? {} : { message: @cause.message, backtrace: @cause.backtrace }
end

def debug_hash
base_json.merge(developer_message: developer_message, error: backtrace, cause: cause_to_hash)
end
end
end
end
end
28 changes: 28 additions & 0 deletions lib/common/client/session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'common/models/base'
require 'common/models/attribute_types/utc_time'
module Common
module Client
# A generic session model - see how RX implements it
class Session < Common::Base
EXPIRATION_THRESHOLD_SECONDS = 20

attribute :user_id, Integer
attribute :expires_at, Common::UTCTime
attribute :token, String

def expired?
return true if expires_at.nil?
expires_at.to_i <= Time.now.utc.to_i + EXPIRATION_THRESHOLD_SECONDS
end

def valid?
user_id.is_a?(Fixnum)
end

def original_json
nil
end
end
end
end
11 changes: 11 additions & 0 deletions lib/common/models/attribute_types/utc_time.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true
module Common
# This is a custom type class for ensuring Time is always coerced as UTC
class UTCTime < Virtus::Attribute
def coerce(value)
return nil if value.to_s.empty?
return Time.parse(value).utc if value.is_a?(String)
value.utc
end
end
end
28 changes: 28 additions & 0 deletions lib/common/models/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'active_model'
require 'common/models/attribute_types/utc_time'

module Common
# This is a base serialization class
class Base
include Comparable
include ActiveModel::Serialization
extend ActiveModel::Naming
include Virtus.model(nullify_blank: true)

attr_reader :attributes
attr_accessor :metadata, :errors
alias to_h attributes
alias to_hash attributes

def initialize(attributes = {})
@attributes = attributes[:data] || attributes
@metadata = attributes[:metadata] || {}
@errors = attributes[:errors] || {}
@attributes.each do |key, value|
setter = "#{key.to_s.underscore}=".to_sym
send(setter, value) if respond_to?(setter)
end
end
end
end
Loading