Class: AJIMS::LTI::OutcomeRequest

Inherits:
Object
  • Object
show all
Includes:
Extensions::Base
Defined in:
lib/ajims/lti/outcome_request.rb

Overview

Class for consuming/generating LTI Outcome Requests

Outcome Request documentation: www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649691

This class can be used by both Tool Providers and Tool Consumers. Each will use it a bit differently. The Tool Provider will use it to POST an OAuth-signed request to a TC. A Tool Consumer will use it to parse such a request from a TP.

Tool Provider Usage

An OutcomeRequest will generally be created through a configured ToolProvider object. See the ToolProvider documentation.

Tool Consumer Usage

When an outcome request is sent from a TP the body of the request is XML. This class parses that XML and provides a simple interface for accessing the information in the request. Typical usage would be:

# create an OutcomeRequest from the request object
req = IMS::LTI::OutcomeRequest.from_post_request(request)

# access the source id to identify the user who's grade you'd like to access
req.lis_result_sourcedid

# process the request
if req.replace_request?
  # set a new score for the user
elsif req.read_request?
  # return the score for the user
elsif req.delete_request?
  # clear the score for the user
else
  # return an unsupported OutcomeResponse
end

Constant Summary collapse

REPLACE_REQUEST =
'replaceResult'
DELETE_REQUEST =
'deleteResult'
READ_REQUEST =
'readResult'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Extensions::Base

#extend_outcome_request, #extend_outcome_response, #outcome_request_extensions, #outcome_response_extensions

Constructor Details

#initialize(opts = {}) ⇒ OutcomeRequest

Create a new OutcomeRequest

Parameters:

  • opts (Hash) (defaults to: {})

    initialization hash



49
50
51
52
53
# File 'lib/ajims/lti/outcome_request.rb', line 49

def initialize(opts={})
  opts.each_pair do |key, val|
    self.send("#{key}=", val) if self.respond_to?("#{key}=")
  end
end

Instance Attribute Details

#consumer_keyObject

Returns the value of attribute consumer_key.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def consumer_key
  @consumer_key
end

#consumer_secretObject

Returns the value of attribute consumer_secret.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def consumer_secret
  @consumer_secret
end

#lis_outcome_service_urlObject

Returns the value of attribute lis_outcome_service_url.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def lis_outcome_service_url
  @lis_outcome_service_url
end

#lis_result_sourcedidObject

Returns the value of attribute lis_result_sourcedid.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def lis_result_sourcedid
  @lis_result_sourcedid
end

#message_identifierObject

Returns the value of attribute message_identifier.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def message_identifier
  @message_identifier
end

#operationObject

Returns the value of attribute operation.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def operation
  @operation
end

#outcome_responseObject

Returns the value of attribute outcome_response.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def outcome_response
  @outcome_response
end

#post_requestObject

Returns the value of attribute post_request.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def post_request
  @post_request
end

#scoreObject

Returns the value of attribute score.



42
43
44
# File 'lib/ajims/lti/outcome_request.rb', line 42

def score
  @score
end

Class Method Details

.from_post_request(post_request) ⇒ Object

Convenience method for creating a new OutcomeRequest from a request object

req = IMS::LTI::OutcomeRequest.from_post_request(request)


58
59
60
61
# File 'lib/ajims/lti/outcome_request.rb', line 58

def self.from_post_request(post_request)
  request = OutcomeRequest.new
  request.process_post_request(post_request)
end

Instance Method Details

#delete_request?Boolean

Check whether this request is a deleteResult request

Returns:

  • (Boolean)


108
109
110
# File 'lib/ajims/lti/outcome_request.rb', line 108

def delete_request?
  @operation == DELETE_REQUEST
end

#outcome_post_successful?Boolean

Check whether the last outcome POST was successful

Returns:

  • (Boolean)


118
119
120
# File 'lib/ajims/lti/outcome_request.rb', line 118

def outcome_post_successful?
  @outcome_response && @outcome_response.success?
end

#post_delete_result!OutcomeResponse

POSTs a deleteResult to the Tool Consumer

Returns:



89
90
91
92
# File 'lib/ajims/lti/outcome_request.rb', line 89

def post_delete_result!
  @operation = DELETE_REQUEST
  post_outcome_request
end

#post_outcome_requestOutcomeResponse

POST an OAuth signed request to the Tool Consumer

Returns:

Raises:



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/ajims/lti/outcome_request.rb', line 125

def post_outcome_request
  raise AJIMS::LTI::InvalidLTIConfigError, "" unless has_required_attributes?

  consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret)
  token = OAuth::AccessToken.new(consumer)

  res = token.post(
    @lis_outcome_service_url,
    generate_request_xml,
    'Content-Type' => 'application/xml'
  )

  @outcome_response = extend_outcome_response(OutcomeResponse.new)
  @outcome_response.process_post_response(res)
end

#post_read_result!OutcomeResponse

POSTs a readResult to the Tool Consumer

Returns:



97
98
99
100
# File 'lib/ajims/lti/outcome_request.rb', line 97

def post_read_result!
  @operation = READ_REQUEST
  post_outcome_request
end

#post_replace_result!(score, submitted_at: nil) ⇒ OutcomeResponse

POSTs the given score to the Tool Consumer with a replaceResult

Returns:



78
79
80
81
82
83
84
# File 'lib/ajims/lti/outcome_request.rb', line 78

def post_replace_result!(score, submitted_at: nil)
  @operation = REPLACE_REQUEST
  @score = score
  @submitted_at = 

  post_outcome_request
end

#process_post_request(post_request) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ajims/lti/outcome_request.rb', line 63

def process_post_request(post_request)
  self.post_request = post_request
  if post_request.body.respond_to?(:read)
    xml = post_request.body.read
    post_request.body.rewind
  else
    xml = post_request.body
  end
  self.process_xml(xml)
  self
end

#process_xml(xml) ⇒ Object

Parse Outcome Request data from XML



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/ajims/lti/outcome_request.rb', line 142

def process_xml(xml)
  doc = REXML::Document.new xml
  @message_identifier = doc.text("//imsx_POXRequestHeaderInfo/imsx_messageIdentifier")
  @lis_result_sourcedid = doc.text("//resultRecord/sourcedGUID/sourcedId")

  if REXML::XPath.first(doc, "//deleteResultRequest")
    @operation = DELETE_REQUEST
  elsif REXML::XPath.first(doc, "//readResultRequest")
    @operation = READ_REQUEST
  elsif REXML::XPath.first(doc, "//replaceResultRequest")
    @operation = REPLACE_REQUEST
    @score = doc.get_text("//resultRecord/result/resultScore/textString")
  end
  extention_process_xml(doc)
end

#read_request?Boolean

Check whether this request is a readResult request

Returns:

  • (Boolean)


113
114
115
# File 'lib/ajims/lti/outcome_request.rb', line 113

def read_request?
  @operation == READ_REQUEST
end

#replace_request?Boolean

Check whether this request is a replaceResult request

Returns:

  • (Boolean)


103
104
105
# File 'lib/ajims/lti/outcome_request.rb', line 103

def replace_request?
  @operation == REPLACE_REQUEST
end