コード例 #1
0
        public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
        {
            MobileServicePreconditionFailedException preconditionFailedException = null;
            JObject result = null;

            do
            {
                preconditionFailedException = null;
                try
                {
                    result = await operation.ExecuteAsync();
                }
                catch (MobileServicePreconditionFailedException ex)
                {
                    preconditionFailedException = ex;
                }

                if (preconditionFailedException != null)
                {
                    var serverItem = preconditionFailedException.Value.ToObject <T>();

                    operation.Item[MobileServiceSystemColumns.Version] = serverItem.Version;
                }
            }while (preconditionFailedException != null);

            return(result);
        }
コード例 #2
0
        public async Task DeleteAsync_ThrowsPreconditionFailedException_WhenMergeConflictOccurs()
        {
            await EnsureEmptyTableAsync <RoundTripTableItemWithSystemPropertiesType>();

            string id = Guid.NewGuid().ToString();
            IMobileServiceTable table = GetClient().GetTable("RoundTripTable");

            var item = new JObject()
            {
                { "id", id }, { "name", "a value" }
            };
            var inserted = await table.InsertAsync(item);

            item["version"] = "3q3A3g==";

            MobileServicePreconditionFailedException expectedException = null;

            try
            {
                await table.DeleteAsync(item);
            }
            catch (MobileServicePreconditionFailedException ex)
            {
                expectedException = ex;
            }
            Assert.IsNotNull(expectedException);
            Assert.AreEqual(expectedException.Value["version"], inserted["version"]);
            Assert.AreEqual(expectedException.Value["name"], inserted["name"]);
        }
コード例 #3
0
        public async Task DeleteAsync_ThrowsPreconditionFailedException_WhenMergeConflictOccurs()
        {
            await EnsureEmptyTableAsync <ToDoWithSystemPropertiesType>();

            string id = "an id";
            IMobileServiceTable table = GetClient().GetTable("stringId_test_table");

            var item = new JObject()
            {
                { "id", id }, { "String", "a value" }
            };
            var inserted = await table.InsertAsync(item);

            item["version"] = "random";

            MobileServicePreconditionFailedException expectedException = null;

            try
            {
                await table.DeleteAsync(item);
            }
            catch (MobileServicePreconditionFailedException ex)
            {
                expectedException = ex;
            }
            Assert.IsNotNull(expectedException);
            Assert.AreEqual(expectedException.Value["version"], inserted["version"]);
            Assert.AreEqual(expectedException.Value["String"], inserted["String"]);
        }
コード例 #4
0
        public async Task DeleteAsync_ThrowsPreconditionFailedException_WhenMergeConflictOccurs_Generic()
        {
            await EnsureEmptyTableAsync <ToDoWithSystemPropertiesType>();

            string id = "an id";
            IMobileServiceTable <ToDoWithSystemPropertiesType> table = GetClient().GetTable <ToDoWithSystemPropertiesType>();

            // insert a new item
            var item = new ToDoWithSystemPropertiesType()
            {
                Id = id, String = "a value"
            };
            await table.InsertAsync(item);

            Assert.IsNotNull(item.CreatedAt);
            Assert.IsNotNull(item.UpdatedAt);
            Assert.IsNotNull(item.Version);

            string version = item.Version;

            // Delete with wrong version
            item.Version = "abc";
            item.String  = "But wait!";
            MobileServicePreconditionFailedException <ToDoWithSystemPropertiesType> expectedException = null;

            try
            {
                await table.DeleteAsync(item);
            }
            catch (MobileServicePreconditionFailedException <ToDoWithSystemPropertiesType> exception)
            {
                expectedException = exception;
            }

            Assert.IsNotNull(expectedException);
            Assert.AreEqual(expectedException.Response.StatusCode, HttpStatusCode.PreconditionFailed);

            string responseContent = await expectedException.Response.Content.ReadAsStringAsync();

            JToken jtoken        = responseContent.ParseToJToken(table.MobileServiceClient.SerializerSettings);
            string serverVersion = (string)jtoken["version"];
            string stringValue   = (string)jtoken["String"];

            Assert.AreEqual(version, serverVersion);
            Assert.AreEqual(stringValue, "a value");

            Assert.IsNotNull(expectedException.Item);
            Assert.AreEqual(version, expectedException.Item.Version);
            Assert.AreEqual(stringValue, expectedException.Item.String);

            // Delete one last time with the version from the server
            item.Version = serverVersion;
            await table.DeleteAsync(item);

            Assert.IsNull(item.Id);
        }
コード例 #5
0
        protected override bool ProceedInvokeException(Exception exception, out Toolkit.Events.ActionResult errorInfo)
        {
            MobileServiceInvalidOperationException mobileServiceInvalidOperationException = exception as MobileServiceInvalidOperationException;

            if (mobileServiceInvalidOperationException != null)
            {
                errorInfo = ActionResult.GetErrorResult(mobileServiceInvalidOperationException);
                return(true);
            }
            MobileServicePreconditionFailedException mobileServicePreconditionFailedException = exception as MobileServicePreconditionFailedException;

            if (mobileServicePreconditionFailedException != null)
            {
                errorInfo = ActionResult.GetErrorResult(mobileServicePreconditionFailedException);
                return(true);
            }
            errorInfo = ActionResult.ValidResult;
            return(false);
        }
コード例 #6
0
ファイル: SyncHandler.cs プロジェクト: kavitha-sant/EvokeDish
        public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
        {
            MobileServicePreconditionFailedException preconditionFailedException = null;
            JObject result = null;

            do
            {
                preconditionFailedException = null;
                try
                {
                    result = await operation.ExecuteAsync();
                }
                catch (MobileServicePreconditionFailedException ex)
                {
                    preconditionFailedException = ex;
                }

                // there is a conflict between the local version and the server version of the item
                if (preconditionFailedException != null)
                {
                    // get the server's version of the item
                    var serverItem = preconditionFailedException.Value.ToObject <T>();

                    // Replace the local pending item's version value with the server item's version value.
                    // This will force the local change to override the server version.
                    // This is somewhat destructive (clobbering), and not favorable for all scenarios.
                    // See the below commented out code for an alternative strategy that is more conservative.
                    operation.Item[MobileServiceSystemColumns.Version] = serverItem.Version;


                    /* The following commented out lines do not force the local copy to the server. Instead, an error message is presented to the user. */
                    /* This could be improved even futher by presenting both versions of the data to the user and letting him/het decide with to keep. */
                    //var localItem = operation.Item.ToObject<Acquaintance>();
                    //RaiseDataSyncErrorEvent(new DataSyncErrorEventArgs<Acquaintance>(localItem, serverItem));
                    //operation.AbortPush();
                    //return result;
                }
            }while (preconditionFailedException != null);

            return(result);
        }
コード例 #7
0
            public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
            {
                MobileServicePreconditionFailedException ex = null;
                JObject result = null;

                do
                {
                    ex = null;
                    try
                    {
                        this.test.Log("Attempting to execute the operation");
                        result = await operation.ExecuteAsync();
                    }
                    catch (MobileServicePreconditionFailedException e)
                    {
                        ex = e;
                    }

                    if (ex != null)
                    {
                        this.test.Log("A MobileServicePreconditionFailedException was thrown, ex.Value = {0}", ex.Value);
                        var serverItem = ex.Value;
                        if (serverItem == null)
                        {
                            this.test.Log("Item not returned in the exception, trying to retrieve it from the server");
                            serverItem = (JObject)(await client.GetTable(operation.Table.TableName).LookupAsync((string)operation.Item["id"]));
                        }

                        var typedClientItem = operation.Item.ToObject <T>();
                        var typedServerItem = serverItem.ToObject <T>();
                        var typedMergedItem = conflictResolution(typedClientItem, typedServerItem);
                        var mergedItem      = JObject.FromObject(typedMergedItem);
                        mergedItem[MobileServiceSystemColumns.Version] = serverItem[MobileServiceSystemColumns.Version];
                        this.test.Log("Merged the items, will try to resubmit the operation");
                        operation.Item = mergedItem;
                    }
                } while (ex != null);

                return(result);
            }
コード例 #8
0
    public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
    {
        JObject result = null;
        MobileServicePreconditionFailedException conflictError = null;

        do
        {
            try
            {
                result = await operation.ExecuteAsync();
            }
            catch (MobileServicePreconditionFailedException e)
            {
                conflictError = e;
            }

            if (conflictError != null)
            {
                // There was a conflict on the server. Let's "fix" it by
                // forcing the client entity
                JObject serverItem = conflictError.Value;

                // In most cases, the server will return the server item in the request body
                // when a Precondition Failed is returned, but it's not guaranteed for all
                // backend types.
                if (serverItem == null)
                {
                    serverItem = (JObject)(await operation.Table.LookupAsync((string)operation.Item[MobileServiceSystemColumns.Id]));
                }

                // Now update the local item with the server version
                operation.Item[MobileServiceSystemColumns.Version] = serverItem[MobileServiceSystemColumns.Version];
            }
        } while (conflictError != null);

        return(result);
    }
コード例 #9
0
        public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
        {
            JObject result = null;
            MobileServicePreconditionFailedException conflictError = null;

            Debug.WriteLine("Beginning Sync");
            do
            {
                try
                {
                    result = await operation.ExecuteAsync();
                }
                catch (MobileServicePreconditionFailedException e)
                {
                    conflictError = e;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                }

                if (conflictError != null)
                {
                    JObject serverItem = conflictError.Value;

                    if (serverItem == null)
                    {
                        serverItem = (JObject)(await operation.Table.LookupAsync((string)operation.Item[MobileServiceSystemColumns.Id]));
                    }


                    serverItem[MobileServiceSystemColumns.Version] = operation.Item[MobileServiceSystemColumns.Version];
                }
            } while (conflictError != null);

            return(result);
        }
コード例 #10
0
            public async Task <JObject> ExecuteTableOperationAsync(IMobileServiceTableOperation operation)
            {
                MobileServicePreconditionFailedException ex = null;
                JObject result = null;

                do
                {
                    ex = null;
                    try
                    {
                        result = await operation.ExecuteAsync();
                    }
                    catch (MobileServicePreconditionFailedException e)
                    {
                        ex = e;
                    }

                    if (ex != null)
                    {
                        var serverItem = ex.Value;
                        if (serverItem == null)
                        {
                            serverItem = (JObject)(await client.GetTable(operation.Table.TableName).LookupAsync((string)operation.Item["id"]));
                        }

                        var typedClientItem = operation.Item.ToObject <T>();
                        var typedServerItem = serverItem.ToObject <T>();
                        var typedMergedItem = conflictResolution(typedClientItem, typedServerItem);
                        var mergedItem      = JObject.FromObject(typedMergedItem);
                        mergedItem[MobileServiceSystemColumns.Version] = serverItem[MobileServiceSystemColumns.Version];
                        operation.Item = mergedItem;
                    }
                } while (ex != null);

                return(result);
            }
コード例 #11
0
        private static ZumoTest CreateOptimisticConcurrencyTest(string testName, Func <VersionedType, VersionedType, VersionedType> mergingPolicy)
        {
            return(new ZumoTest(testName, async delegate(ZumoTest test)
            {
                var client = ZumoTestGlobals.Instance.Client;
                var table = client.GetTable <VersionedType>();
                DateTime now = DateTime.UtcNow;
                int seed = now.Year * 10000 + now.Month * 100 + now.Day;
                test.AddLog("Using seed: {0}", seed);
                Random rndGen = new Random(seed);
                var item = new VersionedType(rndGen);
                await table.InsertAsync(item);
                test.AddLog("[client 1] Inserted item: {0}", item);

                var client2 = new MobileServiceClient(client.ApplicationUri, client.ApplicationKey);
                var table2 = client.GetTable <VersionedType>();
                var item2 = await table2.LookupAsync(item.Id);
                test.AddLog("[client 2] Retrieved the item");
                item2.Name = Util.CreateSimpleRandomString(rndGen, 20);
                item2.Number = rndGen.Next(100000);
                test.AddLog("[client 2] Updated the item, will update on the server now");
                await table2.UpdateAsync(item2);
                test.AddLog("[client 2] Item has been updated: {0}", item2);

                test.AddLog("[client 1] Will try to update; should fail");
                MobileServicePreconditionFailedException <VersionedType> ex = null;
                try
                {
                    item.Name = Util.CreateSimpleRandomString(rndGen, 20);
                    await table.UpdateAsync(item);
                    test.AddLog("[client 1] Error, the update succeeded, but it should have failed. Item = {0}", item);
                    return false;
                }
                catch (MobileServicePreconditionFailedException <VersionedType> e)
                {
                    test.AddLog("[client 1] Received expected exception; server item = {0}", e.Item);
                    ex = e;
                }

                var serverItem = ex.Item;
                if (serverItem.Version != item2.Version)
                {
                    test.AddLog("[client 1] Error, server item's version is not the same as the second item version");
                    return false;
                }

                var cachedMergedItem = mergingPolicy(item, serverItem);
                var mergedItem = mergingPolicy(item, serverItem);
                test.AddLog("[client 1] Merged item: {0}", mergedItem);
                test.AddLog("[client 1] Trying to update it again, should succeed this time");

                await table.UpdateAsync(mergedItem);
                test.AddLog("[client 1] Updated the item: {0}", mergedItem);

                if (!cachedMergedItem.Equals(mergedItem))
                {
                    test.AddLog("[client 1] Error, the server version of the merged item doesn't match the client one");
                    return false;
                }

                test.AddLog("[client 2] Refreshing the item");
                await table2.RefreshAsync(item2);
                test.AddLog("[client 2] Refreshed the item: {0}", item2);

                if (!item2.Equals(mergedItem))
                {
                    test.AddLog("[client] Error, item is different than the item from the client 1");
                    return false;
                }

                return true;
            }));
        }
コード例 #12
0
        public async Task DeleteAsync_ThrowsPreconditionFailedException_WhenMergeConflictOccurs_Generic()
        {
            string id    = Guid.NewGuid().ToString();
            var    table = GetClient().GetTable <RoundTripTableItemWithSystemPropertiesType>();

            // insert a new item
            var item = new RoundTripTableItemWithSystemPropertiesType()
            {
                Id = id, Name = "a value"
            };
            await table.InsertAsync(item);

            Assert.IsNotNull(item.CreatedAt);
            Assert.IsNotNull(item.UpdatedAt);
            Assert.IsNotNull(item.Version);

            string version = item.Version;

            // Delete with wrong version
            item.Version = "3q3A3g==";
            item.Name    = "But wait!";
            MobileServicePreconditionFailedException <RoundTripTableItemWithSystemPropertiesType> expectedException = null;

            try
            {
                await table.DeleteAsync(item);
            }
            catch (MobileServicePreconditionFailedException <RoundTripTableItemWithSystemPropertiesType> exception)
            {
                expectedException = exception;
            }

            Assert.IsNotNull(expectedException);
            Assert.AreEqual(expectedException.Response.StatusCode, HttpStatusCode.PreconditionFailed);

            string responseContent = await expectedException.Response.Content.ReadAsStringAsync();

            RoundTripTableItemWithSystemPropertiesType serverItem = expectedException.Item;
            string serverVersion = serverItem.Version;
            string stringValue   = serverItem.Name;

            Assert.AreEqual(version, serverVersion);
            Assert.AreEqual(stringValue, "a value");

            Assert.IsNotNull(expectedException.Item);
            Assert.AreEqual(version, expectedException.Item.Version);
            Assert.AreEqual(stringValue, expectedException.Item.Name);

            // Delete one last time with the version from the server
            item.Version = serverVersion;
            await table.DeleteAsync(item);

            Assert.IsNull(item.Id);
        }
コード例 #13
0
        public async Task UpdateAsyncWitMergeConflict_Generic()
        {
            await EnsureEmptyTableAsync <RoundTripTableItemWithSystemPropertiesType>();

            string id = Guid.NewGuid().ToString();
            IMobileServiceTable <RoundTripTableItemWithSystemPropertiesType> table = GetClient().GetTable <RoundTripTableItemWithSystemPropertiesType>();

            RoundTripTableItemWithSystemPropertiesType item = new RoundTripTableItemWithSystemPropertiesType()
            {
                Id = id, Name = "a value"
            };
            await table.InsertAsync(item);

            Assert.IsNotNull(item.CreatedAt);
            Assert.IsNotNull(item.UpdatedAt);
            Assert.IsNotNull(item.Version);

            string version = item.Version;

            // Update
            item.Name = "Hello!";
            await table.UpdateAsync(item);

            Assert.IsNotNull(item.Version);
            Assert.AreNotEqual(item.Version, version);

            string newVersion = item.Version;

            // Update again but with the original version
            item.Version = version;
            item.Name    = "But wait!";
            MobileServicePreconditionFailedException <RoundTripTableItemWithSystemPropertiesType> expectedException = null;

            try
            {
                await table.UpdateAsync(item);
            }
            catch (MobileServicePreconditionFailedException <RoundTripTableItemWithSystemPropertiesType> exception)
            {
                expectedException = exception;
            }

            Assert.IsNotNull(expectedException);
            Assert.AreEqual(expectedException.Response.StatusCode, HttpStatusCode.PreconditionFailed);

            Assert.IsNotNull(expectedException.Item);

            string serverVersion = expectedException.Item.Version;
            string stringValue   = expectedException.Item.Name;

            Assert.AreEqual(newVersion, serverVersion);
            Assert.AreEqual(stringValue, "Hello!");

            // Update one last time with the version from the server
            item.Version = serverVersion;
            await table.UpdateAsync(item);

            Assert.IsNotNull(item.Version);
            Assert.AreEqual(item.Name, "But wait!");
            Assert.AreNotEqual(item.Version, serverVersion);

            await table.DeleteAsync(item);
        }