Confirmed users
632
edits
| Line 162: | Line 162: | ||
When the user indicates an issue, the Loop client will create a ZIP file containing information that potentially pertains to the failure. For the initial set of reports, it will include the following files: | When the user indicates an issue, the Loop client will create a ZIP file containing information that potentially pertains to the failure. For the initial set of reports, it will include the following files: | ||
# '''index. | # '''index.json''': Simple text file containing a JSON object. This JSON object contains indexable meta-information relating to the failure report. The format is described in [[#Index_Format]], below. | ||
# '''sdk_log.txt''': All entries in the Browser Console emitted by chrome://browser/content/loop/* | # '''sdk_log.txt''': All entries in the Browser Console emitted by chrome://browser/content/loop/* | ||
# '''stats.txt''': JSON object containing JSON serialization of stats object | # '''stats.txt''': JSON object containing JSON serialization of stats object | ||
| Line 172: | Line 172: | ||
=== Index Format === | === Index Format === | ||
The report IDs will be formed by appending a UUID to the string "le-". | The report IDs will be formed by appending a UUID to the string "le-". | ||
| Line 249: | Line 247: | ||
To that end, we will be using Microsoft Azure blob storage for the report upload and storage. The Loop client will perform PUT requests directly against into a blob container. Azure includes an access control mechanism that allows servers to hand out time-limited signed URLs that can then be used to access the indicated resource. | To that end, we will be using Microsoft Azure blob storage for the report upload and storage. The Loop client will perform PUT requests directly against into a blob container. Azure includes an access control mechanism that allows servers to hand out time-limited signed URLs that can then be used to access the indicated resource. | ||
When a user indicates an issue, the Loop client | When a user indicates an issue, the Loop client collects the data from the index.json file (including a unique issue ID selected by the client), and contacts the Loop server asking for a new URL to store the issue report in: | ||
POST /issue-report HTTP/1.1 | POST /issue-report HTTP/1.1 | ||
| Line 257: | Line 255: | ||
{ | { | ||
"id": "le- | "id": "le-4b42e9ff-5406-4839-90f5-3ccb121ec1a7", | ||
"timestamp": " | "timestamp": "1407784618", | ||
"phase": "midcall", | |||
"type": "incoming", | |||
"client": "builtin", | |||
"channel": "aurora", | |||
"version": "33.0a1", | |||
"callId": "35e7c3a511f424d3b1d6fba442b3a9a5", | |||
"apiKey": "44669102", | |||
"sessionId": "1_MX40NDY2OTEwMn5-V2VkIEp1bCAxNiAwNjo", | |||
"sessionToken": "T1==cGFydG5lcl9pZD00NDY2OTEwMiZzaW", | |||
"simplePushURL": "https://push.services.mozilla.com/update/MGlYke2SrEmYE8ceyu", | |||
"loopServer": "https://loop.services.mozilla.com", | |||
"callerId": "adam@example.com", | |||
"callurl": "http://hello.firefox.com/nxD4V4FflQ", | |||
"dndMode": "available", | |||
"reason": "quality", | |||
"comment": "The video is showing up about one second after the audio", | |||
"okToContact": "true", | |||
"contactEmail": "adam@example.org", | |||
} | } | ||
''Note: the ID is client-provided rather than server-generated to allow for the "retry-after" throttling behavior described below | ''Note: the ID is client-provided rather than server-generated to allow for the "retry-after" throttling behavior described below.'' | ||
Upon receiving such a request, the Loop server performs the following steps: | |||
# Checks that the client does not need to be throttled, | |||
# Stores the received fields in an Azure table, and | |||
# Forms a blob storage URL to upload the information to | |||
==== Report Throttling ==== | |||
To mitigate potential abuse, the Loop server needs to throttle handing out issue URLs on a per-IP basis. If a Loop client attempts to send a request more frequently than the throttle allows, then the Loop server will send an HTTP 429 response indicating how long the client must wait before submitting the report. The client will then re-attempt sending the report once that period has passed. | To mitigate potential abuse, the Loop server needs to throttle handing out issue URLs on a per-IP basis. If a Loop client attempts to send a request more frequently than the throttle allows, then the Loop server will send an HTTP 429 response indicating how long the client must wait before submitting the report. The client will then re-attempt sending the report once that period has passed. | ||
| Line 300: | Line 300: | ||
} | } | ||
This means that, upon startup, the Loop client code needs to check for outstanding (not-yet- | This means that, upon startup, the Loop client code needs to check for outstanding (not-yet-uploaded) reports, and attempt to send them. If a report is over 30 days old and has not been successfully uploaded, clients will delete the report. The Loop server will similarly check that the issueDate field is no older than 30 days, and will reject the request for an upload URL. | ||
==== Data Index Storage ==== | |||
(TBD: basically, the Loop server stores the JSON index object in an Azure table so that developers can search for reports by various criteria. If the client-provided report ID already exists and a file exists in blob storage, the client gets an error) | |||
= | HTTP/1.1 409 Conflict | ||
Access-Control-Allow-Methods: GET,POST | |||
Access-Control-Allow-Origin: https://localhost:3000 | |||
Content-Type: application/json; charset=utf-8 | |||
{ | |||
"code": "409", | |||
"errno": "115", ''// or whatever is allocated for this use'' | |||
"error": "Conflict", | |||
"message": "Report ID already in use" | |||
} | |||
If the client receives such an error, it should assume that the report was previously uploaded successfully without being removed for its own local storage, and deletes the local file. | |||
==== Upload URL Generation ==== | |||
The blob URL fields are constructed as follows: | |||
* The host is the Azure instance assigned to Mozilla's account | |||
* The container is "loop-" followed by a four-digit year and two-digit month (e.g., if the report date sent by the client in its POST request falls in August of 2014, UTC, then the container would be named "loop-201408"). | |||
* The filename is {id}.zip, using the id field provided by the client. | |||
* The "signedversion" field (sv) is the Azure API version we're currently using | |||
* The "signedexpiry" field (se) is the current time plus five minutes (this simply needs to be long enough to upload the report) | |||
* The "signedresource" field (sr) is "b" (blob storage) | |||
* The "signedpermissions" field (sp) is "w" (write only) | |||
* The "signature" field (sig) is computed with our Azure shared key, [http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx as described by the Azure SAS documentation] | |||
This URL is then returned to the user: | |||
HTTP/1.1 200 OK | |||
Access-Control-Allow-Methods: GET,POST | |||
Access-Control-Allow-Origin: https://localhost:3000 | |||
Content-Type: application/json; charset=utf-8 | |||
{ | |||
"issueURL": "https://mozilla.blob.core.windows.net/loop-201408/le-13b09e3f-0839-495e-a9b0-1e917d983766.zip?sv=2012-02-12&se=2014-08-13T08%3a49Z&sr=b&sp=w&sig=Rcp6gQRfV7WDlURdVTqCa%2bqEArnfJxDgE%2bKH3TCChIs%3d" | |||
} | |||
Once | Once it acquires an issue upload URL, the loop client then performs a PUT to the supplied URL to upload the report zipfile. The [http://msdn.microsoft.com/en-us/library/azure/dd135733.aspx Azure REST API documentation] contains more detailed information about this operation. | ||
=== Data Retrieval === | === Data Retrieval === | ||
| Line 388: | Line 354: | ||
=== Data Purging === | === Data Purging === | ||
At the end of each month, a data retention job will locate containers with a name indicating that they exceed the data retention policy for these reports (proposal: 6 months), and remove the containers (including all contained reports). This job also removes corresponding data from the index table. | At the end of each month, a data retention job will locate containers with a name indicating that they exceed the data retention policy for these reports (proposal: 6 months), and remove the containers (including all contained reports). This job also removes corresponding data from the index table. (tbd: table removal can probably be optimized through the use of partitions -- I need to look into Azure table storage a bit more). | ||