LearningLocker / learninglocker

Learning Locker - The Open Source Learning Record Store. Started in 2014.
https://learningpool.com/solutions/learning-record-store-learning-locker/learning-locker-community-overview/
GNU General Public License v3.0
553 stars 276 forks source link

State API requires eTags (should be optional) #490

Closed garemoko closed 9 years ago

garemoko commented 9 years ago

Version Latest from composer as 22nd Jan 2015

Steps to reproduce the bug

  1. Store an application/json document in the State API.
  2. Update the document (PUT) omitting the etag header.

Expected behaviour Document should be accepted, returning 204 no content. Etags are not required for the State API, only the Agent and Activity Profile APIs.

Actual behaviour 400 Bad request is returned.

Server information MongoDB with Basic auth. Running on MAMP.

Client information OS: OS X 10.10.1 Browser: Chrome

Additional information I've tested the client code I'm using against Wax and Cloud and it works.

ryasmi commented 9 years ago

Thanks for the issue and following the guidelines Andrew :+1: this is part of the spec I'm aware of but I was unaware that we didn't do that. This needs to be reported as an issue on the xAPI test suite too I think.

ryasmi commented 9 years ago

I'll try to take a look at fixing this next week for 1.3.2.

ryasmi commented 9 years ago

Hey @garemoko please can you pull issue/490 and tell me if that fixes the issue for you? Thanks :smile:

davidpesce commented 9 years ago

After removing etag from plugin, I'm getting the error, "Error attempting to set registration data to State API."

garemoko commented 9 years ago

what's the full error test below that message? What error code is returned by the LRS?

ryasmi commented 9 years ago

From what I can tell the header is not required in the 490 branch and the ETag isn't checked when storing a document via the State API either. I must be missing something. I'll run the conformance tests against the branch and see how that goes.

davidpesce commented 9 years ago

Full error output:

The Learning Record Store is not available. Please contact a system administrator.

Error attempting to set registration data to State API.

array(3) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
  ["code"]=>
  array(12) {
    [0]=>
    string(22) "HTTP/1.0 404 Not Found"
    [1]=>
    string(35) "Date: Wed, 18 Feb 2015 13:17:29 GMT"
    [2]=>
    string(39) "Server: Apache/2.4.6 (CentOS) PHP/5.6.4"
    [3]=>
    string(19) "Vary: Authorization"
    [4]=>
    string(23) "X-Powered-By: PHP/5.6.4"
    [5]=>
    string(39) "Cache-Control: private, must-revalidate"
    [6]=>
    string(16) "pragma: no-cache"
    [7]=>
    string(11) "expires: -1"
    [8]=>
    string(405) "Set-Cookie: laravel_session=eyJpdiI6IlwvVUJjNnVvQmRGNzcxaUZZT29BbTdFb1FTMGdFUTVtVGNFTGgreU9WSG00PSIsInZhbHVlIjoieWJ0eFhrbjlGc2w0WXZadU55ZldRSzhaOVwveDlmY2RxU2xmd2Zaa1I3TEt2bGRnMXF2RHNsQklDblc3cWdoRGJwSUd1MFNmUWlDMEtvQWltTkRHT3lRPT0iLCJtYWMiOiJhNTNjNDZjMzg4M2FjMTc1MWQ1YTRhM2Q2ZGQzODA4YTU3Y2Y3YTAzMjA5OTUxMjA3ZmNhMTA5ZmViZmY0MzI0In0%3D; expires=Wed, 18-Feb-2015 15:17:29 GMT; Max-Age=7200; path=/; httponly"
    [9]=>
    string(20) "Content-Length: 1986"
    [10]=>
    string(17) "Connection: close"
    [11]=>
    string(30) "Content-Type: application/json"
  }
}
davidpesce commented 9 years ago

I'm running the conformance tests against 490 now. It's been on my todo list to learn how it works. Super simple setup and it's running now.

davidpesce commented 9 years ago

Yowsa! It got 42 errors and then the mochaTest:stage1-core failed. Is there a specific stage or test that you'd like me to test it against?

ryasmi commented 9 years ago

Pull the LL set from my Github. We have a slightly modified version of the suite because we disagree with some of the tests.

ryasmi commented 9 years ago

You need to be on the ll branch of that repo.

davidpesce commented 9 years ago

Conformance test output:

  4265 passing (10m)
  242 pending
  5 failing

  1) State concurrency Good state concurrency: correctMatchWithRegistration request cluster Then the stateConcurrency response is verified:

      Uncaught AssertionError: "9404f3e9c267c819ec754de3e853b4dd4dfde33e" == "102b16ce866bbbb6cea75cb663dcdcb0712100a3"
      + expected - actual

      +102b16ce866bbbb6cea75cb663dcdcb0712100a3
      -9404f3e9c267c819ec754de3e853b4dd4dfde33e

      at Object.obj.validate (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\fixtures\clusters\stateConcurrency.js:40:40)
      at Object.<anonymous> (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\steps\verify.js:119:43)
      at Request._callback (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\utils\request.js:239:13)
      at Request.self.callback (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\request\request.js:123:22)
      at Request.emit (events.js:98:17)
      at Request.<anonymous> (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\request\request.js:1047:14)
      at Request.emit (events.js:117:20)
      at IncomingMessage.<anonymous> (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\request\request.js:998:12)
      at IncomingMessage.emit (events.js:117:20)
      at _stream_readable.js:943:16

  2) State concurrency Bad state concurrency: incorrectNoneMatch request cluster Then the LRS responds with HTTP 412:
     Uncaught AssertionError: Response status: 204, expected: [412]
      at Object.module.exports.statusCodes (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\utils\assertions.js:9:16)
      at Object.library.then.main (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\steps\base.js:283:20)
      at Object.invoke (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:32:19)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Macro.js:50:12)
      at interpret_step (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:71:47)
      at iterator (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:63:19)
      at iterate (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:72:13)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:78:9)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:27:23)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:58:21)

  3) State concurrency Bad state concurrency: incorrectMatch request cluster Then the LRS responds with HTTP 412:
     Uncaught AssertionError: Response status: 204, expected: [412]
      at Object.module.exports.statusCodes (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\utils\assertions.js:9:16)
      at Object.library.then.main (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\steps\base.js:283:20)
      at Object.invoke (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:32:19)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Macro.js:50:12)
      at interpret_step (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:71:47)
      at iterator (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:63:19)
      at iterate (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:72:13)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:78:9)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:27:23)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:58:21)

  4) State concurrency Bad state concurrency: ifMatchAndIfNoneMatch request cluster Then the LRS responds with HTTP 412:
     Uncaught AssertionError: Response status: 204, expected: [412]
      at Object.module.exports.statusCodes (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\utils\assertions.js:9:16)
      at Object.library.then.main (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\steps\base.js:283:20)
      at Object.invoke (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:32:19)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Macro.js:50:12)
      at interpret_step (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:71:47)
      at iterator (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:63:19)
      at iterate (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:72:13)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:78:9)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:27:23)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:58:21)

  5) statement structure id test Bad id: '7396683c-0759-e411-b974-a0d3c123d81f' ("e" in 3rd segment not acceptable version) Then the LRS responds with
 HTTP 200:
     AssertionError: Response status: 409, expected: [200]
      at Object.module.exports.statusCodes (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\utils\assertions.js:9:16)
      at Object.library.then.main (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\steps\base.js:283:20)
      at Object.invoke (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:32:19)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Macro.js:50:12)
      at interpret_step (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:71:47)
      at iterator (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:63:19)
      at iterate (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:72:13)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Array.js:78:9)
      at Array.each_async (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\fn.js:27:23)
      at interpret (Z:\git\forks\ryansmith94\xAPI_LRS_Test-ll\src\node_modules\yadda\lib\Interpreter.js:58:21)

Warning: Task "mochaTest:stage1-core" failed. Use --force to continue.
garemoko commented 9 years ago

I'm surprised that you're getting 404 when setting the state; I could understand it for getting State.

ryasmi commented 9 years ago

Yeah I'm super confused about this. If you guys can get the exact request(s) out for me I can probably figure this out pretty fast.

davidpesce commented 9 years ago

@garemoko, is there a quick way to do this? Maybe add it to the debug output?

davidpesce commented 9 years ago

I think this is the request:

Encoded:

http://scrubbed/data/xAPIactivities/state?activityId=Test+TC+via+LMS&agent=%7B%22name%22%3A%22Admin+User%22%2C%22mbox%22%3A%22mailto%3Asupport%40scrubbed%22%2C%22objectType%22%3A%22Agent%22%7D&stateId=http%3A%2F%2Ftincanapi.co.uk%2Fstateapikeys%2Fregistrations

Decoded:

http://scrubbed/data/xAPIactivities/state?activityId=Test TC via LMS&agent={"name":"Admin User","mbox":"mailto:support@scrubbed","objectType":"Agent"}&stateId=http://tincanapi.co.uk/stateapikeys/registrations
garemoko commented 9 years ago

looks like thats missing a slash, which explains the 404. That'd be a bug in the plugin. Should be http://scrubbed/data/xAPI/activities/state

davidpesce commented 9 years ago

Well this goes back to the fact that I can't get it to display this screen unless I don't include a trailing slash in the plugin settings.

davidpesce commented 9 years ago

Addressed the missing slash issue and am now back to getting a 400 bad request error.

Request:

http://scrubbed/data/xAPI/activities/state?activityId=http://scrubbed/test1/story.html&agent={"name":"Admin User","mbox":"mailto:support@scrubbed","objectType":"Agent"}&stateId=http://tincanapi.co.uk/stateapikeys/registrations

Full error:

The Learning Record Store is not available. Please contact a system administrator.

Error attempting to set registration data to State API.

array(3) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
  ["code"]=>
  array(13) {
    [0]=>
    string(24) "HTTP/1.0 400 Bad Request"
    [1]=>
    string(35) "Date: Wed, 18 Feb 2015 22:57:38 GMT"
    [2]=>
    string(39) "Server: Apache/2.4.6 (CentOS) PHP/5.6.4"
    [3]=>
    string(19) "Vary: Authorization"
    [4]=>
    string(23) "X-Powered-By: PHP/5.6.4"
    [5]=>
    string(39) "Cache-Control: private, must-revalidate"
    [6]=>
    string(16) "pragma: no-cache"
    [7]=>
    string(11) "expires: -1"
    [8]=>
    string(31) "X-Experience-API-Version: 1.0.1"
    [9]=>
    string(407) "Set-Cookie: laravel_session=eyJpdiI6IlZrbXdwSDg2UWk0K1JUblkyZUE5YnRkZVZpWjd5bnpDeEFsNkQ5VWhaTk09IiwidmFsdWUiOiJRblIzSGVxeCtkcStWS1wvSndZTlhLOWZsc2pLamlhUE1rUW1kYXhPMGZDektRN2VMaHBjbkJ2a0dlelo5aWRLWGNwSUx0V05EK2kzalgwc3VwYXRVQkE9PSIsIm1hYyI6ImE2M2VhODY0MWRkMDFlZDY3ODE1MjQ1NmIzZjJiOGIzZWVhMjRhZTJiMmYxYWMyMjQ0MTZjNDA2ODMzZWI1MzIifQ%3D%3D; expires=Thu, 19-Feb-2015 00:57:38 GMT; Max-Age=7200; path=/; httponly"
    [10]=>
    string(20) "Content-Length: 4317"
    [11]=>
    string(17) "Connection: close"
    [12]=>
    string(30) "Content-Type: application/json"
  }
}

@ryansmith94 I'd like to get back to LL1.3.3. Is there anything else you'd like me to test before doing so?

ryasmi commented 9 years ago

Pulll issue/490 @garemoko @davidpesce. Made changes to that branch, should fix these issues.

ryasmi commented 9 years ago

I think #490, #491, and #493 should be fixed now. Let me know. garemoko/moodle-mod_tincanlaunch#20

davidpesce commented 9 years ago

Getting further!

New error is:

The Learning Record Store is not available. Please contact a system administrator.

Error attempting to set learner preferences to Agent Profile API.

array(2) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
}

Here's the request:

http://scrubbed/data/xAPIagents/profile?agent={"name":"Admin User","mbox":"mailto:support@scrubbed","objectType":"Agent"}&profileId=CMI5LearnerPreferences
ryasmi commented 9 years ago

Nice, you're missing the slash again between xAPI and agents

davidpesce commented 9 years ago

Gah! Sorry about that. I'm getting:

Error attempting to send 'launched' statement.

array(2) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
}

I'm going to troubleshoot a bit deeper when I've had my coffee. Although, I think that verifies that this issue is fixed. Right?!

ryasmi commented 9 years ago

Sounds like it! :-D I'll wait to see how your troubleshooting goes though

On Thu, 19 Feb 2015 12:06 davidpesce notifications@github.com wrote:

Gah! Sorry about that. I'm getting:

Error attempting to send 'launched' statement.

array(2) { ["contents"]=> bool(false) ["metadata"]=> NULL }

I'm going to troubleshoot a bit deeper when I've had my coffee. Although, I think that verifies that this issue is fixed. Right?!

— Reply to this email directly or view it on GitHub https://github.com/LearningLocker/learninglocker/issues/490#issuecomment-75041411 .

davidpesce commented 9 years ago

Back to the same error again.

Request:

http://scrubbed/data/xAPI/agents/profile?agent={"name":"Admin User","mbox":"mailto:support@scrubbed","objectType":"Agent"}&profileId=CMI5LearnerPreferences

Error output:

The Learning Record Store is not available. Please contact a system administrator.

Error attempting to set learner preferences to Agent Profile API.

array(2) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
}
ryasmi commented 9 years ago

If you're running a local version of LL, please clear your app/storage/logs/laravel.log file then run the code that causes the error and paste the contents of the laravel log file here.

On Thu, 19 Feb 2015 13:37 davidpesce notifications@github.com wrote:

Back to the same error again.

Request:

http://scrubbed/data/xAPI/agents/profile?agent={"name":"Admin User","mbox":"mailto:support@scrubbed","objectType":"Agent"}&profileId=CMI5LearnerPreferences

Error output:

The Learning Record Store is not available. Please contact a system administrator.

Error attempting to set learner preferences to Agent Profile API.

array(2) { ["contents"]=> bool(false) ["metadata"]=> NULL }

— Reply to this email directly or view it on GitHub https://github.com/LearningLocker/learninglocker/issues/490#issuecomment-75052683 .

davidpesce commented 9 years ago

No, it's running on a server as production. I tried doing what you said and the log didn't add any new content.

ryasmi commented 9 years ago

Ok. Assuming you're talking about the Learning Locker log, this sounds very fishy to me and I would suggest that the issue here is either regarding validation or the plugin itself. I'll need more information though I think. I can't really tell too much from that request and the response doesn't look like a LL response to me.

On Thu Feb 19 2015 at 2:12:19 PM davidpesce notifications@github.com wrote:

No, it's running on a server as production. I tried doing what you said and the log didn't add any new content.

— Reply to this email directly or view it on GitHub https://github.com/LearningLocker/learninglocker/issues/490#issuecomment-75057505 .

davidpesce commented 9 years ago

Yeah, LL is not local. I believe the LL designations are local vs production, right?

Should the log be recreated/updated after clearing?

ryasmi commented 9 years ago

Normally yeah. Yes the log should be updated after clearing. If it's deleted it should be recreated (to the best of my knowledge).

On Thu Feb 19 2015 at 2:26:00 PM davidpesce notifications@github.com wrote:

Yeah, LL is not local. I believe the LL designations are local vs production, right?

Should the log be recreated/updated after clearing?

— Reply to this email directly or view it on GitHub https://github.com/LearningLocker/learninglocker/issues/490#issuecomment-75059708 .

davidpesce commented 9 years ago

OK, went back to a direct LL URL and it does in fact recreate the laravel.log.

garemoko commented 9 years ago

You might need to add some more error handling into https://github.com/garemoko/moodle-mod_tincanlaunch/blob/master/locallib.php#L359 to work out why stream_get_contents is returning 'false'

ryasmi commented 9 years ago

Awesome, let me know what the log contains after your testing.

On Thu, 19 Feb 2015 15:06 davidpesce notifications@github.com wrote:

OK, went back to a direct LL URL and it does in fact recreate the laravel.log.

— Reply to this email directly or view it on GitHub https://github.com/LearningLocker/learninglocker/issues/490#issuecomment-75066776 .

davidpesce commented 9 years ago

Interestingly, we're not getting a response at all.

@garemoko - that's just the line I hit!

davidpesce commented 9 years ago

OK, I caught the exception within fopen.

ERRORobject(Exception)#129 (7) {
  ["message":protected]=>
  string(17) "File open failed."
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(0)
  ["file":protected]=>
  string(78) "/var/www/html/scrubbed/public/mod/tincanlaunch/locallib.php"
  ["line":protected]=>
  int(397)
  ["trace":"Exception":private]=>
  array(2) {
    [0]=>
    array(4) {
      ["file"]=>
      string(78) "/var/www/html/scrubbed/public/mod/tincanlaunch/locallib.php"
      ["line"]=>
      int(359)
      ["function"]=>
      string(30) "tincanlaunch_save_agentprofile"
      ["args"]=>
      array(7) {
        [0]=>
        &array(1) {
          ["languagePreference"]=>
          string(5) "en-US"
        }
        [1]=>
        &string(44) "http://scrubbed/data/xAPI"
        [2]=>
        &string(40) "5f39f65009d738431ea542a2be98d7147306a220"
        [3]=>
        &string(40) "cceef37de9bfa0e474e2ee5f9fc230632ae3e747"
        [4]=>
        &string(5) "1.0.1"
        [5]=>
        &array(3) {
          ["name"]=>
          string(10) "Admin User"
          ["mbox"]=>
          string(38) "mailto:support@scrubbed"
          ["objectType"]=>
          string(5) "Agent"
        }
        [6]=>
        &string(22) "CMI5LearnerPreferences"
      }
    }
    [1]=>
    array(4) {
      ["file"]=>
      string(76) "/var/www/html/scrubbed/public/mod/tincanlaunch/launch.php"
      ["line"]=>
      int(135)
      ["function"]=>
      string(56) "tincanlaunch_get_global_parameters_and_save_agentprofile"
      ["args"]=>
      array(2) {
        [0]=>
        &array(1) {
          ["languagePreference"]=>
          string(5) "en-US"
        }
        [1]=>
        &string(22) "CMI5LearnerPreferences"
      }
    }
  }
  ["previous":"Exception":private]=>
  NULL
}
davidpesce commented 9 years ago

For my own sanity, I used postman to send the request. Here's what is returned:

{
"error": true,
"success": false,
"message": "Check the current state of the resource then set the \"If-Match\" header with the current ETag to resolve the conflict.",
"trace": "#0 \/var\/www\/learninglocker\/app\/locker\/repository\/Document\/EloquentDocumentRepository.php(455): Locker\\Repository\\Document\\EloquentDocumentRepository->checkETag('\"2BE88CA4242C76...', NULL, NULL)\ #1 \/var\/www\/learninglocker\/app\/locker\/repository\/Document\/EloquentDocumentRepository.php(101): Locker\\Repository\\Document\\EloquentDocumentRepository->storeAgentDoc('54c51c597285d12...', Array, '2015-02-19T17:1...', 'PUT')\ #2 \/var\/www\/learninglocker\/app\/controllers\/xapi\/DocumentController.php(94): Locker\\Repository\\Document\\EloquentDocumentRepository->store('54c51c597285d12...', 'agentProfile', Array, '2015-02-19T17:1...', 'PUT')\ #3 \/var\/www\/learninglocker\/app\/controllers\/xapi\/DocumentController.php(113): Controllers\\xAPI\\DocumentController->store()\ #4 \/var\/www\/learninglocker\/app\/controllers\/xapi\/BaseController.php(37): Controllers\\xAPI\\DocumentController->update()\ #5 [internal function]: Controllers\\xAPI\\BaseController->selectMethod()\ #6 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Controller.php(231): call_user_func_array(Array, Array)\ #7 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ControllerDispatcher.php(93): Illuminate\\Routing\\Controller->callAction('selectMethod', Array)\ #8 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ControllerDispatcher.php(62): Illuminate\\Routing\\ControllerDispatcher->call(Object(Controllers\\xAPI\\AgentController), Object(Illuminate\\Routing\\Route), 'selectMethod')\ #9 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php(962): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request), 'Controllers\\\\xAP...', 'selectMethod')\ #10 [internal function]: Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()\ #11 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Route.php(109): call_user_func_array(Object(Closure), Array)\ #12 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php(1028): Illuminate\\Routing\\Route->run(Object(Illuminate\\Http\\Request))\ #13 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Router.php(996): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))\ #14 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php(776): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))\ #15 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php(746): Illuminate\\Foundation\\Application->dispatch(Object(Illuminate\\Http\\Request))\ #16 \/var\/www\/learninglocker\/vendor\/asm89\/stack-cors\/src\/Asm89\/Stack\/Cors.php(51): Illuminate\\Foundation\\Application->handle(Object(Illuminate\\Http\\Request), 1, true)\ #17 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/Middleware.php(72): Asm89\\Stack\\Cors->handle(Object(Illuminate\\Http\\Request), 1, true)\ #18 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Cookie\/Queue.php(47): Illuminate\\Session\\Middleware->handle(Object(Illuminate\\Http\\Request), 1, true)\ #19 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Cookie\/Guard.php(51): Illuminate\\Cookie\\Queue->handle(Object(Illuminate\\Http\\Request), 1, true)\ #20 \/var\/www\/learninglocker\/vendor\/stack\/builder\/src\/Stack\/StackedHttpKernel.php(23): Illuminate\\Cookie\\Guard->handle(Object(Illuminate\\Http\\Request), 1, true)\ #21 \/var\/www\/learninglocker\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Application.php(642): Stack\\StackedHttpKernel->handle(Object(Illuminate\\Http\\Request))\ #22 \/var\/www\/learninglocker\/public\/index.php(49): Illuminate\\Foundation\\Application->run()\ #23 {main}"
}

Seems like eTag is still required.

davidpesce commented 9 years ago

For anyone finding this issue in the future, this resource explains a good deal about actors/agents: http://tincanapi.com/2013/06/05/deep-dive-actor-agent/

davidpesce commented 9 years ago

Since this issue is related to the State API requiring etags, I'm calling it fixed.

I'm going to move over to https://github.com/garemoko/moodle-mod_tincanlaunch/issues/20 to continue troubleshooting.

garemoko commented 9 years ago

"Seems like eTag is still required." - if this is true then the issue is not fixed.

davidpesce commented 9 years ago

I was thinking since this issue is related to State API, we may want to open another one for Agent API requiring eTag.

garemoko commented 9 years ago

Oh sorry, I missed that we'd moved on from state. The Agent API is supposed to require an etag.

davidpesce commented 9 years ago

Yeah, and I think my errors are because I removed that aspect of it. I got a little delete happy with the etags. I'm going to keep the 490 branch for now and revert back to your latest for the plugin.

ryasmi commented 9 years ago

This should now be resolved on the develop branch.

ryasmi commented 9 years ago

Had to make a few changes to pass the conformance tests that may effect this issue. If someone can test this issue with the issue/conformance branch that would be awesome.

davidpesce commented 9 years ago

I'll take a look. Any issues using my existing mail, app, database.php files?

davidpesce commented 9 years ago

Darn, it's busted. That being said, I think it's the quotes you added (in DocumentController).

Error attempting to set registration data to State API.

array(4) {
  ["contents"]=>
  bool(false)
  ["metadata"]=>
  NULL
  ["code"]=>
  array(13) {
    [0]=>
    string(32) "HTTP/1.0 412 Precondition Failed"
    [1]=>
    string(35) "Date: Wed, 25 Feb 2015 15:11:57 GMT"
    [2]=>
    string(39) "Server: Apache/2.4.6 (CentOS) PHP/5.6.4"
    [3]=>
    string(19) "Vary: Authorization"
    [4]=>
    string(23) "X-Powered-By: PHP/5.6.4"
    [5]=>
    string(39) "Cache-Control: private, must-revalidate"
    [6]=>
    string(16) "pragma: no-cache"
    [7]=>
    string(11) "expires: -1"
    [8]=>
    string(31) "X-Experience-API-Version: 1.0.1"
    [9]=>
    string(405) "Set-Cookie: laravel_session=eyJpdiI6IkZaVm4rRlA4aWV3Z3hNdjNhWnA5VjRxZ2RXRE95RUVJdGJXeGtSWDJROEk9IiwidmFsdWUiOiJFRkJIUEVsUGNDWFFhWDJvbHBEcHF5NEVcLzJVa1wvd3RKWmNKaVlMNGozenQwRWtNYXcxcHlNdTZLd0I2YldFd2R4Y3VxblVERFZhUXZOVVJMQUFaZTVRPT0iLCJtYWMiOiJlNmRjMGU2Njc3MjQxODc4NzhiZDc3ZTU1YWNmNGQwOWMxM2ZkM2NjMDFiZmRiNGNlNzdjNGFkN2MxZjA2ZDNlIn0%3D; expires=Wed, 25-Feb-2015 17:11:57 GMT; Max-Age=7200; path=/; httponly"
    [10]=>
    string(20) "Content-Length: 3937"
    [11]=>
    string(17) "Connection: close"
    [12]=>
    string(30) "Content-Type: application/json"
  }
  ["EtagHeader"]=>
  string(55) "If-Match : ""2BE88CA4242C76E8253AC62474851065032D6833"""
}
davidpesce commented 9 years ago

@garemoko Thoughts on this? I can strip out the quotes on the plugin side, but is that appropriate?

I think I'll try getting rid of the quotes on our end and test it against scorm cloud. Stay tuned.

ryasmi commented 9 years ago

You're right, this is a LL issue. I need to create a migration for you. Apologies.

ryasmi commented 9 years ago

Just wrote a migration. You need to run php artisan migrate --env=YOUR_ENV. Then you should be ok to test it out :smile: Replace YOUR_ENV with your environment name (i.e. 'local', 'production', etc).