public static void SendStatement(string activity) { string email = "mailto:"; email += username; Statement[] statements = new Statement[1]; Activity newAct = new Activity("http://35.9.22.105/xapi"); LanguageMap inter = new LanguageMap(); inter.Add("en-US", "Interacted"); System.Uri verbURI = new System.Uri("http://verbs/interaction/"); StatementVerb interact = new StatementVerb(verbURI, inter); newAct.Definition = new ActivityDefinition(); newAct.Definition.Name = new LanguageMap(); newAct.Definition.Description = new LanguageMap(); newAct.Definition.Description.Add("type", "Desktop Application Learning Activity"); newAct.Definition.Name.Add("en-US", activity); Random rand = new Random(); int random = rand.Next(); newAct.Id = "http://" + random.ToString() + "/desktopapp/" + activity; statements[0] = new Statement(new Actor(username, email), interact, newAct); try { tincan.StoreStatements(statements); } catch (Exception e) { _offlineQueuedStatements.Enqueue(statements[0]); } }
/// <summary> /// Returns the specified number of statements off the top of the queue as a statement array /// </summary> /// <param name="count">The maximum number of statements to pull</param> /// <returns>An array of statements from the queue or null if empty</returns> /// <remarks>Returning null or an empty array is up to the implementer. Our TCAPI implementation supports either method.</remarks> public Statement[] GetQueuedStatements(int count) { if (count > statementList.Count) count = statementList.Count; if (count == 0) return null; Statement[] statements = new Statement[count]; for (int i = 0; i < count; i++) statements[i] = statementList[i]; return statements; }
public static void JSObject() { Console.WriteLine("Start\n\n"); //TCAPI tincan = new TCAPI(new Uri("http://35.9.22.105:8000/xapi"), new BasicHTTPAuth("Dave", "12345")); Statement[] statements = new Statement[1]; Activity newAct = new Activity("http://www.google.com"); newAct.Definition = new ActivityDefinition(); newAct.Definition.Name = new LanguageMap(); newAct.Definition.Name.Add("en-US", "Testing"); statements[0] = new Statement(new Actor("Guess Who", "mailto:guesswho"), new StatementVerb(PredefinedVerbs.Created), newAct); TCAPI tincan = new TCAPI(new Uri("http://35.9.22.105:8000/xapi"), new BasicHTTPAuth("Joe", "123"), RusticiSoftware.TinCanAPILibrary.Helper.TCAPIVersion.TinCan1p0p0); tincan.StoreStatements(statements); Console.WriteLine("End\n"); }
/// <summary> /// Returns true if the statements were sent successfully /// </summary> /// <returns></returns> public static bool ResendQueuedStatements() { bool sendSuccessful = false; try { while (_offlineQueuedStatements.Count > 0) { Statement[] tempStatements = new Statement[1]; tempStatements[0] = _offlineQueuedStatements.Peek(); tincan.StoreStatements(tempStatements); // If it makes it to this point, an exception wasn't thrown and the statement was sent successfully _offlineQueuedStatements.Dequeue(); sendSuccessful = true; } } catch (Exception e) { sendSuccessful = false; } return sendSuccessful; }
/// <summary> /// Adds the set of statements to the Queue /// </summary> /// <param name="statements">Statements to enqueue</param> public void AddToStatementQueue(Statement[] statements) { foreach (Statement s in statements) statementList.Add(s); }
/// <summary> /// Voids a series of statements using the administrator actor /// </summary> /// <param name="statementIdsToVoid">A list of statement IDs</param> /// <param name="synchronous"></param> public void VoidStatements(string[] statementIdsToVoid, bool synchronous) { if (synchronous) { VoidStatements(statementIdsToVoid); return; } TinCanJsonConverter converter = new TinCanJsonConverter(); Statement[] statements = new Statement[statementIdsToVoid.Length]; for (int i = 0; i < statementIdsToVoid.Length; i++) { Statement voided = new Statement(); switch (version) { case TCAPIVersion.TinCan090: voided.Object = new Model.TinCan090.TargetedStatement(statementIdsToVoid[i]); break; default: voided.Object = new StatementRef(statementIdsToVoid[i]); break; } voided.Verb = new StatementVerb(PredefinedVerbs.Voided); voided.Actor = adminActor; statements[i] = voided; } offlineStorage.AddToStatementQueue(statements); }
/// <summary> /// Voids a series of statements using the administrator actor /// </summary> /// <param name="statementIdsToVoid">A list of statement IDs</param> /// <param name="synchronous"></param> public void VoidStatements(string[] statementIdsToVoid) { Statement[] statementsToVoid = new Statement[statementIdsToVoid.Length]; for (int i = 0; i < statementIdsToVoid.Length; i++) { Statement voided = new Statement(); switch (version) { case TCAPIVersion.TinCan090: voided.Object = new Model.TinCan090.TargetedStatement(statementIdsToVoid[i]); break; default: voided.Object = new StatementRef(statementIdsToVoid[i]); break; } voided.Verb = new StatementVerb(PredefinedVerbs.Voided); voided.Actor = adminActor; statementsToVoid[i] = voided; } StoreStatements(statementsToVoid); }
/// <summary> /// Stores multiple statements asynchronously /// </summary> /// <param name="statements">An array of statements to store</param> /// <param name="synchronous">When true, stores statements synchronously. When false, adds the statements to the queue.</param> /// <remarks></remarks> public void StoreStatements(Statement[] statements, bool synchronous) { if (synchronous) { StoreStatements(statements); return; } foreach (Statement s in statements) { var failures = new List<ValidationFailure>(s.Validate(earlyReturnOnFailure: true)); if (failures.Count > 0) { throw new ArgumentException(failures[0].Error, "statements"); } } offlineStorage.AddToStatementQueue(statements); }
/// <summary> ///A test for StoreStatements ///</summary> //[TestMethod()] public void StoreStatementsAsyncTest() { TCAPI target = new TCAPI("https://cloud.scorm.com/ScormEngineInterface/TCAPI/CZSWMUZPSE", new BasicHTTPAuth("CZSWMUZPSE", "vwiuflgsY22FDXpHA4lwwe5hrnUXvcyJjW3fDrpH"), new TCAPICallback(), new OfflineStorage(), 750, 2); Statement[] statements = new Statement[6]; for (int i = 0; i < statements.Length; i++) { int j = i % 3; switch (j) { case 0: statements[i] = new Statement(new Actor("Mufasa", "mailto:[email protected]"), new StatementVerb(PredefinedVerbs.Experienced), new TinCanActivity("test activity")); break; case 1: statements[i] = new Statement(new Actor("Carl", "mailto:[email protected]"), new StatementVerb(PredefinedVerbs.Experienced), new TinCanActivity("TinCanClientLibrary")); break; case 2: statements[i] = new Statement(new Actor("DiBiase", "mailto:[email protected]"), new StatementVerb(PredefinedVerbs.Experienced), new TinCanActivity("test activity")); break; } } target.StoreStatements(statements, false); //target.Flush(); Statement[] statementSize; while ((statementSize = target.OfflineStorage.GetQueuedStatements(1)) != null && (statementSize.Length > 0)) { Thread.Sleep(500); Console.WriteLine("Waiting"); } target.Dispose(); // Releases the thread timer handle // If all statements successfully flush out of the buffer AND no exceptions are thrown (which should repopulate the buffer) // then the test was successful and the final statementSize should be null, indicating an empty queue. // The default implementation returns a null object. However you may also return a size-0 array, all checks ensure both. Assert.IsTrue(statementSize == null || statementSize.Length == 0); }
/// <summary> /// Stores a single statement /// </summary> /// <param name="statement">The statement to store</param> public void StoreStatement(Statement statement) { StoreStatements(new Statement[] { statement }); }
/// <summary> /// Retreives a statement with a given ID /// </summary> /// <param name="statementId">Statement to retreive</param> /// <returns>The statement with this ID</returns> public Statement GetStatement(string statementId) { Statement statement = new Statement(); statement.Id = statementId; TinCanJsonConverter converter = new TinCanJsonConverter(); string statementToGet = converter.SerializeToJSON(statement); NameValueCollection nvc = new NameValueCollection(); nvc["statementId"] = statementId; string result = HttpMethods.GetRequest(nvc, endpoint + STATEMENTS, authentification, versionString); Statement statementResult = null; switch (version) { case TCAPIVersion.TinCan090: statementResult = (Statement)((Model.TinCan090.Statement)converter.DeserializeJSON(result, typeof(Model.TinCan090.Statement))); break; case TCAPIVersion.TinCan095: statementResult = (Statement)converter.DeserializeJSON(result, typeof(Statement)); break; } return statementResult; }
/// <summary> /// Stores statements synchronously, must be called from a separate thread /// </summary> /// <param name="statements">Statements to store</param> /// <param name="callback">Callback to signal upon completion</param> private void StoreStatements(Statement[] statements, AsyncPostCallback callback) { // Break the statement into a 2D array. First index is the number of batches, second is the number of // statements in that batch, which is either maxBatchSize or statements.Length % maxBatchSize Statement[][] batches = new Statement[(statements.Length - 1) / maxBatchSize + 1][]; for (int i = 0; i < batches.Length; i++) { batches[i] = new Statement[statements.Length - (maxBatchSize * (i + 1)) >= 0 ? maxBatchSize : statements.Length % maxBatchSize]; Array.Copy(statements, i * maxBatchSize, batches[i], 0, batches[i].Length); } for (int round = 0; round < batches.Length; round++) { foreach (Statement s in batches[round]) { var failures = new List<ValidationFailure>(s.Validate(earlyReturnOnFailure: true)); if (failures.Count > 0) { throw new ArgumentException(failures[0].Error, "statements"); } } TinCanJsonConverter converter = new TinCanJsonConverter(); string postData; switch (version) { case TCAPIVersion.TinCan090: Model.TinCan090.Statement[] currentBatch = new RusticiSoftware.TinCanAPILibrary.Model.TinCan090.Statement[batches[round].Length]; for (int i = 0; i < currentBatch.Length; i++) currentBatch[i] = (Model.TinCan090.Statement)batches[round][i]; postData = converter.SerializeToJSON(currentBatch); break; default: postData = converter.SerializeToJSON(batches[round]); break; } HttpMethods.PostRequest(postData, endpoint + STATEMENTS, authentification, callback, versionString); } }
/// <summary> /// This method is fired by the AsyncPostCallback every time FlushAsync succeeds. /// </summary> private void PostSuccess(Statement[] statements) { offlineStorage.RemoveStatementsFromQueue(statements.Length); }
private void PostFailed(Statement[] statements, Exception e) { offlineStorage.RemoveStatementsFromQueue(statements.Length); }
/// <summary> /// Stores multiple statements asynchronously /// </summary> /// <param name="statements">An array of statements to store</param> /// <param name="synchronous">When true, stores statements synchronously. When false, adds the statements to the queue.</param> /// <remarks></remarks> public void StoreStatements(Statement[] statements, bool synchronous) { if (synchronous) { StoreStatements(statements); return; } foreach (Statement s in statements) { s.Validate(); } offlineStorage.AddToStatementQueue(statements); }
/// <summary> /// Handles the case in which the statements fail to post /// </summary> /// <param name="failedBatch">The batch of statements that failed</param> /// <param name="e">The thrown exception, usually a webexception</param> public void StatementsFailed(Statement[] failedBatch, Exception e) { throw e; }
/// <summary> /// Indicator of storing success. This will allow the TCAPI object to continue Asynchronous flushing. /// </summary> /// <param name="statements"></param> public void StatementsStored(Statement[] statements) { }
/// <summary> /// Stores a single statement asynchronously /// </summary> /// <param name="statement">The statement to store</param> public void StoreStatement(Statement statement, bool synchronous) { StoreStatements(new Statement[] { statement }, synchronous); }
/// <summary> ///A test for StoreStatement ///</summary> /// //[TestMethod()] public void StoreStatementTest() { TCAPI target = new TCAPI("http://cloud.scorm.com/ScormEngineInterface/TCAPI/public", new BasicHTTPAuth("test", "password")); target.MaxBatchSize = 1; Statement[] statements = new Statement[1]; TinCanActivity activity = new TinCanActivity("http://www.example.com"); activity.Definition = new ActivityDefinition(); activity.Definition.Name = new LanguageMap(); activity.Definition.Name.Add("en-US", "TCAPI C# 0.95 Library."); statements[0] = new Statement(new Actor("Example", "mailto:[email protected]"), new StatementVerb(PredefinedVerbs.Experienced), activity); target.StoreStatements(statements); Assert.Inconclusive(INCONCLUSIVE); }
/// <summary> /// Stores multiple statements /// </summary> /// <param name="statements">An array of statements to store</param> public void StoreStatements(Statement[] statements) { StoreStatements(statements, null); }