public ParseCommand(ParseCommand other) { this.Uri = other.Uri; this.Method = other.Method; this.DataObject = other.DataObject; this.Headers = new List <KeyValuePair <string, string> >(other.Headers); }
public ParseCommand(ParseCommand other) { this.Uri = other.Uri; this.Method = other.Method; this.DataObject = other.DataObject; this.Headers = new List<KeyValuePair<string, string>>(other.Headers); this.Data = other.Data; }
public Task RevokeAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("logout", method: "POST", sessionToken: sessionToken, data: new Dictionary<string, object>()); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }
private Task <ParseCommand> PrepareCommand(ParseCommand command) { ParseCommand newCommand = new ParseCommand(command); // Disabled //Task<ParseCommand> installationIdTask = installationIdController.GetAsync().ContinueWith(t => //{ // newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Installation-Id", t.Result.ToString())); // return newCommand; //}); // TODO (richardross): Inject configuration instead of using shared static here. ParseClient.Configuration configuration = ParseClient.CurrentConfiguration; newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Application-Id", configuration.ApplicationID)); newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Client-Version", ParseClient.VersionString)); if (configuration.AuxiliaryHeaders != null) { foreach (KeyValuePair <string, string> header in configuration.AuxiliaryHeaders) { newCommand.Headers.Add(header); } } if (!String.IsNullOrEmpty(configuration.VersionInfo.BuildVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-App-Build-Version", configuration.VersionInfo.BuildVersion)); } if (!String.IsNullOrEmpty(configuration.VersionInfo.DisplayVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-App-Display-Version", configuration.VersionInfo.DisplayVersion)); } if (!String.IsNullOrEmpty(configuration.VersionInfo.OSVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-OS-Version", configuration.VersionInfo.OSVersion)); } // TODO (richardross): I hate the idea of having this super tightly coupled static variable in here. // Lets eventually get rid of it. if (!String.IsNullOrEmpty(ParseClient.MasterKey)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Master-Key", ParseClient.MasterKey)); } else { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Windows-Key", configuration.Key)); } // TODO (richardross): Inject this instead of using static here. if (ParseUser.IsRevocableSessionEnabled) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Revocable-Session", revocableSessionTokentrueValue)); } return(Task.FromResult(newCommand)); //return new Task<ParseCommand>(() => { return newCommand; }); }
public Task RevokeAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("logout", method: "POST", sessionToken: sessionToken, data: new Dictionary <string, object>()); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken)); }
public Task RequestPasswordResetAsync(string email, CancellationToken cancellationToken) { var command = new ParseCommand("requestPasswordReset", method: "POST", data: new Dictionary <string, object> { { "email", email } }); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken)); }
public Task<IObjectState> UpgradeToRevocableSessionAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("upgradeToRevocableSession", method: "POST", sessionToken: sessionToken, data: new Dictionary<string, object>()); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); }); }
public Task<IObjectState> GetSessionAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("sessions/me", method: "GET", sessionToken: sessionToken, data: null); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); }); }
public Task SendPushNotificationAsync(IPushState state, CancellationToken cancellationToken) { return currentUserController.GetCurrentSessionTokenAsync(cancellationToken).OnSuccess(sessionTokenTask => { var command = new ParseCommand("push", method: "POST", sessionToken: sessionTokenTask.Result, data: ParsePushEncoder.Instance.Encode(state)); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }).Unwrap(); }
public Task <IObjectState> UpgradeToRevocableSessionAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("upgradeToRevocableSession", method: "POST", sessionToken: sessionToken, data: new Dictionary <string, object>()); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); })); }
public Task <IObjectState> GetUserAsync(string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("users/me", method: "GET", sessionToken: sessionToken, data: null); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); })); }
public void TestMakeCommand() { ParseCommand command = new ParseCommand("endpoint", method: "GET", sessionToken: "abcd", headers: null, data: null); Assert.AreEqual("/1/endpoint", command.Uri.AbsolutePath); Assert.AreEqual("GET", command.Method); Assert.IsTrue(command.Headers.Any(pair => pair.Key == "X-Parse-Session-Token" && pair.Value == "abcd")); }
public Task DeleteAsync(IObjectState state, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("classes/{0}/{1}", state.ClassName, state.ObjectId), method: "DELETE", sessionToken: sessionToken, data: null); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken)); }
Task <ParseCommand> PrepareCommand(ParseCommand command) { ParseCommand newCommand = new ParseCommand(command); Task <ParseCommand> installationIdTask = InstallationIdController.GetAsync().ContinueWith(t => { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Installation-Id", t.Result.ToString())); return(newCommand); }); // TODO: Inject configuration instead of using shared static here. ParseClient.Configuration configuration = ParseClient.CurrentConfiguration; newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Application-Id", configuration.ApplicationID)); newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Client-Version", ParseClient.VersionString)); if (configuration.AuxiliaryHeaders != null) { foreach (KeyValuePair <string, string> header in configuration.AuxiliaryHeaders) { newCommand.Headers.Add(header); } } if (!String.IsNullOrEmpty(configuration.VersionInfo.BuildVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-App-Build-Version", configuration.VersionInfo.BuildVersion)); } if (!String.IsNullOrEmpty(configuration.VersionInfo.DisplayVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-App-Display-Version", configuration.VersionInfo.DisplayVersion)); } if (!String.IsNullOrEmpty(configuration.VersionInfo.OSVersion)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-OS-Version", configuration.VersionInfo.OSVersion)); } if (!String.IsNullOrEmpty(configuration.MasterKey)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Master-Key", configuration.MasterKey)); } else if (!String.IsNullOrEmpty(configuration.Key)) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Windows-Key", configuration.Key)); } // TODO: Inject this instead of using static here. if (ParseUser.IsRevocableSessionEnabled) { newCommand.Headers.Add(new KeyValuePair <string, string>("X-Parse-Revocable-Session", "1")); } return(installationIdTask); }
public Task <FileState> SaveAsync(FileState state, Stream dataStream, string sessionToken, IProgress <ParseUploadProgressEventArgs> progress, CancellationToken cancellationToken = default(CancellationToken)) { if (state.Url != null) { // !isDirty return(Task <FileState> .FromResult(state)); } if (cancellationToken.IsCancellationRequested) { var tcs = new TaskCompletionSource <FileState>(); tcs.TrySetCanceled(); return(tcs.Task); } var oldPosition = dataStream.Position; var command = new ParseCommand("files/" + state.Name, method: "POST", sessionToken: sessionToken, contentType: state.MimeType, stream: dataStream); return(commandRunner.RunCommandAsync(command, uploadProgress: progress, cancellationToken: cancellationToken).OnSuccess(uploadTask => { var result = uploadTask.Result; var jsonData = result.Item2; cancellationToken.ThrowIfCancellationRequested(); return new FileState { Name = jsonData["name"] as string, Url = new Uri(jsonData["url"] as string, UriKind.Absolute), MimeType = state.MimeType }; }).ContinueWith(t => { // Rewind the stream on failure or cancellation (if possible) if ((t.IsFaulted || t.IsCanceled) && dataStream.CanSeek) { dataStream.Seek(oldPosition, SeekOrigin.Begin); } return t; }).Unwrap()); }
public Task<IObjectState> FetchAsync(IObjectState state, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("classes/{0}/{1}", Uri.EscapeDataString(state.ClassName), Uri.EscapeDataString(state.ObjectId)), method: "GET", sessionToken: sessionToken, data: null); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); }); }
public Task <ParseConfig> FetchConfigAsync(string sessionToken, CancellationToken cancellationToken) { ParseCommand command = new ParseCommand("config", method: "GET", sessionToken: sessionToken, data: null); return(Runner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(task => { cancellationToken.ThrowIfCancellationRequested(); return new ParseConfig(task.Result.Item2); }).OnSuccess(task => { cancellationToken.ThrowIfCancellationRequested(); CurrentConfigController.SetCurrentConfigAsync(task.Result); return task; }).Unwrap()); }
public Task <IObjectState> FetchAsync(IObjectState state, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("classes/{0}/{1}", Uri.EscapeDataString(state.ClassName), Uri.EscapeDataString(state.ObjectId)), method: "GET", sessionToken: sessionToken, data: null); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); })); }
public Task<ParseConfig> FetchConfigAsync(String sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand("config", method: "GET", sessionToken: sessionToken, data: null); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(task => { cancellationToken.ThrowIfCancellationRequested(); return new ParseConfig(task.Result.Item2); }).OnSuccess(task => { cancellationToken.ThrowIfCancellationRequested(); CurrentConfigController.SetCurrentConfigAsync(task.Result); return task; }).Unwrap(); }
private Task <IDictionary <string, object> > FindAsync(string className, IDictionary <string, object> parameters, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("classes/{0}?{1}", Uri.EscapeDataString(className), ParseClient.BuildQueryString(parameters)), method: "GET", sessionToken: sessionToken, data: null); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { return t.Result.Item2; })); }
public Task<IObjectState> SignUpAsync(IObjectState state, IDictionary<string, IParseFieldOperation> operations, CancellationToken cancellationToken) { var objectJSON = ParseObject.ToJSONObjectForSaving(operations); var command = new ParseCommand("classes/_User", method: "POST", data: objectJSON); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = true; }); return serverState; }); }
public Task TrackAppOpenedAsync(string pushHash, string sessionToken, CancellationToken cancellationToken) { IDictionary<string, object> data = new Dictionary<string, object> { { "at", DateTime.Now } }; if (pushHash != null) { data["push_hash"] = pushHash; } var command = new ParseCommand("events/AppOpened", method: "POST", sessionToken: sessionToken, data: PointerOrLocalIdEncoder.Instance.Encode(data) as IDictionary<string, object>); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }
public Task <IObjectState> SignUpAsync(IObjectState state, IDictionary <string, IParseFieldOperation> operations, CancellationToken cancellationToken) { var objectJSON = ParseObject.ToJSONObjectForSaving(operations); var command = new ParseCommand("classes/_User", method: "POST", data: objectJSON); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = true; }); return serverState; })); }
private Task<ParseCommand> PrepareCommand(ParseCommand command) { ParseCommand newCommand = new ParseCommand(command); Task<ParseCommand> installationIdTask = installationIdController.GetAsync().ContinueWith(t => { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Installation-Id", t.Result.ToString())); return newCommand; }); // TODO (richardross): Inject configuration instead of using shared static here. ParseClient.Configuration configuration = ParseClient.CurrentConfiguration; newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Application-Id", configuration.ApplicationId)); newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Client-Version", ParseClient.VersionString)); if (configuration.AdditionalHTTPHeaders != null) { foreach (var header in configuration.AdditionalHTTPHeaders) { newCommand.Headers.Add(header); } } if (!string.IsNullOrEmpty(configuration.VersionInfo.BuildVersion)) { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-App-Build-Version", configuration.VersionInfo.BuildVersion)); } if (!string.IsNullOrEmpty(configuration.VersionInfo.DisplayVersion)) { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-App-Display-Version", configuration.VersionInfo.DisplayVersion)); } if (!string.IsNullOrEmpty(configuration.VersionInfo.OSVersion)) { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-OS-Version", configuration.VersionInfo.OSVersion)); } // TODO (richardross): I hate the idea of having this super tightly coupled static variable in here. // Lets eventually get rid of it. if (!string.IsNullOrEmpty(ParseClient.MasterKey)) { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Master-Key", ParseClient.MasterKey)); } else { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Windows-Key", configuration.WindowsKey)); } // TODO (richardross): Inject this instead of using static here. if (ParseUser.IsRevocableSessionEnabled) { newCommand.Headers.Add(new KeyValuePair<string, string>("X-Parse-Revocable-Session", revocableSessionTokenTrueValue)); } return installationIdTask; }
public Task <T> CallFunctionAsync <T>(String name, IDictionary <string, object> parameters, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("functions/{0}", Uri.EscapeUriString(name)), method: "POST", sessionToken: sessionToken, data: NoObjectsEncoder.Instance.Encode(parameters) as IDictionary <string, object>); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var decoded = ParseDecoder.Instance.Decode(t.Result.Item2) as IDictionary <string, object>; if (!decoded.ContainsKey("result")) { return default(T); } return Conversion.To <T>(decoded["result"]); })); }
public Task<FileState> SaveAsync(FileState state, Stream dataStream, String sessionToken, IProgress<ParseUploadProgressEventArgs> progress, CancellationToken cancellationToken = default(CancellationToken)) { if (state.Url != null) { // !isDirty return Task<FileState>.FromResult(state); } if (cancellationToken.IsCancellationRequested) { var tcs = new TaskCompletionSource<FileState>(); tcs.TrySetCanceled(); return tcs.Task; } var oldPosition = dataStream.Position; var command = new ParseCommand("files/" + state.Name, method: "POST", sessionToken: sessionToken, contentType: state.MimeType, stream: dataStream); return commandRunner.RunCommandAsync(command, uploadProgress: progress, cancellationToken: cancellationToken).OnSuccess(uploadTask => { var result = uploadTask.Result; var jsonData = result.Item2; cancellationToken.ThrowIfCancellationRequested(); return new FileState { Name = jsonData["name"] as string, Url = new Uri(jsonData["url"] as string, UriKind.Absolute), MimeType = state.MimeType }; }).ContinueWith(t => { // Rewind the stream on failure or cancellation (if possible) if ((t.IsFaulted || t.IsCanceled) && dataStream.CanSeek) { dataStream.Seek(oldPosition, SeekOrigin.Begin); } return t; }).Unwrap(); }
public Task TrackEventAsync(string name, IDictionary<string, string> dimensions, string sessionToken, CancellationToken cancellationToken) { IDictionary<string, object> data = new Dictionary<string, object> { { "at", DateTime.Now }, { "name", name }, }; if (dimensions != null) { data["dimensions"] = dimensions; } var command = new ParseCommand("events/" + name, method: "POST", sessionToken: sessionToken, data: PointerOrLocalIdEncoder.Instance.Encode(data) as IDictionary<string, object>); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }
public Task<IObjectState> LogInAsync(string authType, IDictionary<string, object> data, CancellationToken cancellationToken) { var authData = new Dictionary<string, object>(); authData[authType] = data; var command = new ParseCommand("users", method: "POST", data: new Dictionary<string, object> { {"authData", authData} }); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; }); }
public Task TestRunCommand() { var mockHttpClient = new Mock<IHttpClient>(); var mockInstallationIdController = new Mock<IInstallationIdController>(); var fakeResponse = Task<Tuple<HttpStatusCode, string>>.FromResult(new Tuple<HttpStatusCode, string>(HttpStatusCode.OK, "{}")); mockHttpClient.Setup(obj => obj.ExecuteAsync(It.IsAny<HttpRequest>(), It.IsAny<IProgress<ParseUploadProgressEventArgs>>(), It.IsAny<IProgress<ParseDownloadProgressEventArgs>>(), It.IsAny<CancellationToken>())).Returns(fakeResponse); mockInstallationIdController.Setup(i => i.GetAsync()).Returns(Task.FromResult<Guid?>(null)); ParseCommandRunner commandRunner = new ParseCommandRunner(mockHttpClient.Object, mockInstallationIdController.Object); var command = new ParseCommand("endpoint", method: "GET", data: null); return commandRunner.RunCommandAsync(command).ContinueWith(t => { Assert.False(t.IsFaulted); Assert.False(t.IsCanceled); Assert.IsInstanceOf(typeof(IDictionary<string, object>), t.Result.Item2); Assert.AreEqual(0, t.Result.Item2.Count); }); }
public Task<IObjectState> LogInAsync(string username, string password, CancellationToken cancellationToken) { var data = new Dictionary<string, object>{ {"username", username}, {"password", password} }; var command = new ParseCommand(string.Format("login?{0}", ParseClient.BuildQueryString(data)), method: "GET", data: null); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; }); }
public Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(ParseCommand command, IProgress<ParseUploadProgressEventArgs> uploadProgress = null, IProgress<ParseDownloadProgressEventArgs> downloadProgress = null, CancellationToken cancellationToken = default(CancellationToken)) { return PrepareCommand(command).ContinueWith(commandTask => { return httpClient.ExecuteAsync(commandTask.Result, uploadProgress, downloadProgress, cancellationToken).OnSuccess(t => { cancellationToken.ThrowIfCancellationRequested(); var response = t.Result; var contentString = response.Item2; int responseCode = (int)response.Item1; if (responseCode >= 500) { // Server error, return InternalServerError. throw new ParseException(ParseException.ErrorCode.InternalServerError, response.Item2); } else if (contentString != null) { IDictionary<string, object> contentJson = null; try { if (contentString.StartsWith("[")) { var arrayJson = Json.Parse(contentString); contentJson = new Dictionary<string, object> { { "results", arrayJson } }; } else { contentJson = Json.Parse(contentString) as IDictionary<string, object>; } } catch (Exception e) { throw new ParseException(ParseException.ErrorCode.OtherCause, "Invalid response from server", e); } if (responseCode < 200 || responseCode > 299) { int code = (int)(contentJson.ContainsKey("code") ? (long)contentJson["code"] : (int)ParseException.ErrorCode.OtherCause); string error = contentJson.ContainsKey("error") ? contentJson["error"] as string : contentString; throw new ParseException((ParseException.ErrorCode)code, error); } return new Tuple<HttpStatusCode, IDictionary<string, object>>(response.Item1, contentJson); } return new Tuple<HttpStatusCode, IDictionary<string, object>>(response.Item1, null); }); }).Unwrap(); }
public Task <IObjectState> LogInAsync(string username, string password, CancellationToken cancellationToken) { var data = new Dictionary <string, object> { { "username", username }, { "password", password } }; var command = new ParseCommand(string.Format("login?{0}", ParseClient.BuildQueryString(data)), method: "GET", data: null); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; })); }
public Task<IObjectState> SaveAsync(IObjectState state, IDictionary<string, IParseFieldOperation> operations, string sessionToken, CancellationToken cancellationToken) { var objectJSON = ParseObject.ToJSONObjectForSaving(operations); var command = new ParseCommand((state.ObjectId == null ? string.Format("classes/{0}", Uri.EscapeDataString(state.ClassName)) : string.Format("classes/{0}/{1}", Uri.EscapeDataString(state.ClassName), state.ObjectId)), method: (state.ObjectId == null ? "POST" : "PUT"), sessionToken: sessionToken, data: objectJSON); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; }); }
public Task <IObjectState> SaveAsync(IObjectState state, IDictionary <string, IParseFieldOperation> operations, string sessionToken, CancellationToken cancellationToken) { var objectJSON = ParseObject.ToJSONObjectForSaving(operations); var command = new ParseCommand((state.ObjectId == null ? string.Format("classes/{0}", Uri.EscapeDataString(state.ClassName)) : string.Format("classes/{0}/{1}", Uri.EscapeDataString(state.ClassName), state.ObjectId)), method: (state.ObjectId == null ? "POST" : "PUT"), sessionToken: sessionToken, data: objectJSON); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; })); }
public Task <IObjectState> LogInAsync(string authType, IDictionary <string, object> data, CancellationToken cancellationToken) { var authData = new Dictionary <string, object>(); authData[authType] = data; var command = new ParseCommand("users", method: "POST", data: new Dictionary <string, object> { { "authData", authData } }); return(commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).OnSuccess(t => { var serverState = ParseObjectCoder.Instance.Decode(t.Result.Item2, ParseDecoder.Instance); serverState = serverState.MutatedClone(mutableClone => { mutableClone.IsNew = t.Result.Item1 == System.Net.HttpStatusCode.Created; }); return serverState; })); }
public Task TestRunCommandWithInvalidString() { var mockHttpClient = new Mock<IHttpClient>(); var mockInstallationIdController = new Mock<IInstallationIdController>(); var fakeResponse = Task<Tuple<HttpStatusCode, string>>.FromResult(new Tuple<HttpStatusCode, string>(HttpStatusCode.OK, "invalid")); mockHttpClient.Setup(obj => obj.ExecuteAsync(It.IsAny<HttpRequest>(), It.IsAny<IProgress<ParseUploadProgressEventArgs>>(), It.IsAny<IProgress<ParseDownloadProgressEventArgs>>(), It.IsAny<CancellationToken>())).Returns(fakeResponse); mockInstallationIdController.Setup(i => i.GetAsync()).Returns(Task.FromResult<Guid?>(null)); ParseCommandRunner commandRunner = new ParseCommandRunner(mockHttpClient.Object, mockInstallationIdController.Object); var command = new ParseCommand("endpoint", method: "GET", data: null); return commandRunner.RunCommandAsync(command).ContinueWith(t => { Assert.True(t.IsFaulted); Assert.False(t.IsCanceled); Assert.IsInstanceOf<ParseException>(t.Exception.InnerException); var parseException = t.Exception.InnerException as ParseException; Assert.AreEqual(ParseException.ErrorCode.OtherCause, parseException.Code); }); }
private IList<Task<IDictionary<string, object>>> ExecuteBatchRequest(IList<ParseCommand> requests, string sessionToken, CancellationToken cancellationToken) { var tasks = new List<Task<IDictionary<string, object>>>(); int batchSize = requests.Count; var tcss = new List<TaskCompletionSource<IDictionary<string, object>>>(); for (int i = 0; i < batchSize; ++i) { var tcs = new TaskCompletionSource<IDictionary<string, object>>(); tcss.Add(tcs); tasks.Add(tcs.Task); } var encodedRequests = requests.Select(r => { var results = new Dictionary<string, object> { { "method", r.Method }, { "path", r.Uri.AbsolutePath }, }; if (r.DataObject != null) { results["body"] = r.DataObject; } return results; }).Cast<object>().ToList(); var command = new ParseCommand("batch", method: "POST", sessionToken: sessionToken, data: new Dictionary<string, object> { { "requests", encodedRequests } }); commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { foreach (var tcs in tcss) { if (t.IsFaulted) { tcs.TrySetException(t.Exception); } else if (t.IsCanceled) { tcs.TrySetCanceled(); } } return; } var resultsArray = Conversion.As<IList<object>>(t.Result.Item2["results"]); int resultLength = resultsArray.Count; if (resultLength != batchSize) { foreach (var tcs in tcss) { tcs.TrySetException(new InvalidOperationException( "Batch command result count expected: " + batchSize + " but was: " + resultLength + ".")); } return; } for (int i = 0; i < batchSize; ++i) { var result = resultsArray[i] as Dictionary<string, object>; var tcs = tcss[i]; if (result.ContainsKey("success")) { tcs.TrySetResult(result["success"] as IDictionary<string, object>); } else if (result.ContainsKey("error")) { var error = result["error"] as IDictionary<string, object>; long errorCode = (long)error["code"]; tcs.TrySetException(new ParseException((ParseException.ErrorCode)errorCode, error["error"] as string)); } else { tcs.TrySetException(new InvalidOperationException( "Invalid batch command response.")); } } }); return tasks; }
public Task DeleteAsync(IObjectState state, string sessionToken, CancellationToken cancellationToken) { var command = new ParseCommand(string.Format("classes/{0}/{1}", state.ClassName, state.ObjectId), method: "DELETE", sessionToken: sessionToken, data: null); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }
private IList <Task <IDictionary <string, object> > > ExecuteBatchRequest(IList <ParseCommand> requests, string sessionToken, CancellationToken cancellationToken) { var tasks = new List <Task <IDictionary <string, object> > >(); int batchSize = requests.Count; var tcss = new List <TaskCompletionSource <IDictionary <string, object> > >(); for (int i = 0; i < batchSize; ++i) { var tcs = new TaskCompletionSource <IDictionary <string, object> >(); tcss.Add(tcs); tasks.Add(tcs.Task); } var encodedRequests = requests.Select(r => { var results = new Dictionary <string, object> { { "method", r.Method }, { "path", r.Uri.AbsolutePath }, }; if (r.DataObject != null) { results["body"] = r.DataObject; } return(results); }).Cast <object>().ToList(); var command = new ParseCommand("batch", method: "POST", sessionToken: sessionToken, data: new Dictionary <string, object> { { "requests", encodedRequests } }); commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken).ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { foreach (var tcs in tcss) { if (t.IsFaulted) { tcs.TrySetException(t.Exception); } else if (t.IsCanceled) { tcs.TrySetCanceled(); } } return; } var resultsArray = Conversion.As <IList <object> >(t.Result.Item2["results"]); int resultLength = resultsArray.Count; if (resultLength != batchSize) { foreach (var tcs in tcss) { tcs.TrySetException(new InvalidOperationException( "Batch command result count expected: " + batchSize + " but was: " + resultLength + ".")); } return; } for (int i = 0; i < batchSize; ++i) { var result = resultsArray[i] as Dictionary <string, object>; var tcs = tcss[i]; if (result.ContainsKey("success")) { tcs.TrySetResult(result["success"] as IDictionary <string, object>); } else if (result.ContainsKey("error")) { var error = result["error"] as IDictionary <string, object>; long errorCode = (long)error["code"]; tcs.TrySetException(new ParseException((ParseException.ErrorCode)errorCode, error["error"] as string)); } else { tcs.TrySetException(new InvalidOperationException( "Invalid batch command response.")); } } }); return(tasks); }
public Task <Tuple <HttpStatusCode, IDictionary <string, object> > > RunCommandAsync(ParseCommand command, IProgress <ParseUploadProgressEventArgs> uploadProgress = null, IProgress <ParseDownloadProgressEventArgs> downloadProgress = null, CancellationToken cancellationToken = default(CancellationToken)) { return(PrepareCommand(command).ContinueWith(commandTask => { return httpClient.ExecuteAsync(commandTask.Result, uploadProgress, downloadProgress, cancellationToken).OnSuccess(t => { cancellationToken.ThrowIfCancellationRequested(); var response = t.Result; var contentString = response.Item2; int responseCode = (int)response.Item1; if (responseCode >= 500) { // Server error, return InternalServerError. throw new ParseException(ParseException.ErrorCode.InternalServerError, response.Item2); } else if (contentString != null) { IDictionary <string, object> contentJson = null; try { if (contentString.StartsWith("[")) { var arrayJson = Json.Parse(contentString); contentJson = new Dictionary <string, object> { { "results", arrayJson } }; } else { contentJson = Json.Parse(contentString) as IDictionary <string, object>; } } catch (Exception e) { throw new ParseException(ParseException.ErrorCode.OtherCause, "Invalid response from server", e); } if (responseCode < 200 || responseCode > 299) { int code = (int)(contentJson.ContainsKey("code") ? (long)contentJson["code"] : (int)ParseException.ErrorCode.OtherCause); string error = contentJson.ContainsKey("error") ? contentJson["error"] as string : contentString; throw new ParseException((ParseException.ErrorCode)code, error); } return new Tuple <HttpStatusCode, IDictionary <string, object> >(response.Item1, contentJson); } return new Tuple <HttpStatusCode, IDictionary <string, object> >(response.Item1, null); }); }).Unwrap()); }
public Task RequestPasswordResetAsync(string email, CancellationToken cancellationToken) { var command = new ParseCommand("requestPasswordReset", method: "POST", data: new Dictionary<string, object> { {"email", email} }); return commandRunner.RunCommandAsync(command, cancellationToken: cancellationToken); }
/// <summary> /// Runs a specified <see cref="ParseCommand"/>. /// </summary> /// <param name="command">The <see cref="ParseCommand"/> to run.</param> /// <param name="uploadProgress">An <see cref="IProgress{ParseUploadProgressEventArgs}"/> instance to push upload progress data to.</param> /// <param name="downloadProgress">An <see cref="IProgress{ParseDownloadProgressEventArgs}"/> instance to push download progress data to.</param> /// <param name="cancellationToken">An asynchronous operation cancellation token that dictates if and when the operation should be cancelled.</param> /// <returns></returns> public Task <Tuple <HttpStatusCode, IDictionary <string, object> > > RunCommandAsync(ParseCommand command, IProgress <ParseUploadProgressEventArgs> uploadProgress = null, IProgress <ParseDownloadProgressEventArgs> downloadProgress = null, CancellationToken cancellationToken = default) { return(PrepareCommand(command).ContinueWith(commandTask => { return httpClient.ExecuteAsync(commandTask.Result, uploadProgress, downloadProgress, cancellationToken).OnSuccess(t => { cancellationToken.ThrowIfCancellationRequested(); Tuple <HttpStatusCode, string> response = t.Result; string contentString = response.Item2; int responseCode = (int)response.Item1; if (responseCode >= 500) { // Server error, return InternalServerError. throw new ParseException(ParseException.ErrorCode.InternalServerError, response.Item2); } else if (contentString != null) { IDictionary <string, object> contentJson = null; try { // TODO: Newer versions of Parse Server send the failure results back as HTML. contentJson = contentString.StartsWith("[") ? new Dictionary <string, object> { ["results"] = Json.Parse(contentString) } : Json.Parse(contentString) as IDictionary <string, object>; } catch (Exception e) { throw new ParseException(ParseException.ErrorCode.OtherCause, "Invalid or alternatively-formatted response recieved from server.", e); } if (responseCode < 200 || responseCode > 299) { int code = (int)(contentJson.ContainsKey("code") ? (long)contentJson["code"] : (int)ParseException.ErrorCode.OtherCause); string error = contentJson.ContainsKey("error") ? contentJson["error"] as string : contentString; throw new ParseException((ParseException.ErrorCode)code, error); } return new Tuple <HttpStatusCode, IDictionary <string, object> >(response.Item1, contentJson); } return new Tuple <HttpStatusCode, IDictionary <string, object> >(response.Item1, null); }); }).Unwrap()); }