Example #1
0
        public static void EnableSynonyms()
        {
            try
            {
                int MaxNumTries = 3;

                for (int i = 0; i < MaxNumTries; ++i)
                {
                    try
                    {
                        //connect to Azure Search
                        SearchServiceClient serviceClient = CreateSearchServiceClient();

                        Index index = serviceClient.Indexes.Get("eecip");
                        index = AddSynonymMapsToFields(index);

                        // The IfNotChanged condition ensures that the index is updated only if the ETags match.
                        serviceClient.Indexes.CreateOrUpdate(index, accessCondition: AccessCondition.IfNotChanged(index));

                        Console.WriteLine("Updated the index successfully.\n");
                        break;
                    }
                    catch (CloudException e) when(e.IsAccessConditionFailed())
                    {
                        Console.WriteLine($"Index update failed : {e.Message}. Attempt({i}/{MaxNumTries}).\n");
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public void IfNotChangedThrowsOnEmptyETag()
        {
            IResourceWithETag aResourceWithETag = new AResourceWithETag()
            {
                ETag = string.Empty
            };

            Assert.Throws <ArgumentException>(() => AccessCondition.IfNotChanged(aResourceWithETag));
        }
        public void IfNotChangedReturnsIfMatchAccessCondition()
        {
            IResourceWithETag aResourceWithETag = new AResourceWithETag()
            {
                ETag = "IHazETag"
            };

            AccessCondition result = AccessCondition.IfNotChanged(aResourceWithETag);

            Assert.Equal(aResourceWithETag.ETag, result.IfMatch);
            Assert.Null(result.IfNoneMatch);
        }
        internal static void DeleteIfNotChangedWorksOnlyOnCurrentResource <T>(
            Action <string, SearchRequestOptions, AccessCondition> deleteAction,
            Func <T> createResource,
            Func <T, T> updateResource,
            string resourceName)
            where T : IResourceWithETag
        {
            Action <string, AccessCondition> delete = (a, b) => deleteAction(a, null, b);
            var staleResource   = createResource();
            var currentResource = updateResource(staleResource);

            SearchAssert.ThrowsCloudException(
                () => delete(resourceName, AccessCondition.IfNotChanged(staleResource)),
                e => e.IsAccessConditionFailed());
            delete(resourceName, AccessCondition.IfNotChanged(currentResource));
        }
        internal static void UpdateIfNotChangedSucceedsWhenResourceUnchanged <T>(
            Func <T, SearchRequestOptions, AccessCondition, T> createOrUpdateFunc,
            Func <T> newResourceDefinition,
            Func <T, T> mutateResourceDefinition)
            where T : IResourceWithETag
        {
            Func <T, AccessCondition, T> createOrUpdate = (a, b) => createOrUpdateFunc(a, null, b);
            var createdResource = createOrUpdate(newResourceDefinition(), AccessCondition.GenerateEmptyCondition());
            var mutatedResource = mutateResourceDefinition(createdResource);

            var updatedResource = createOrUpdate(mutatedResource, AccessCondition.IfNotChanged(createdResource));

            Assert.NotEmpty(createdResource.ETag);
            Assert.NotEmpty(updatedResource.ETag);
            Assert.NotEqual(createdResource.ETag, updatedResource.ETag);
        }
Example #6
0
        public static void UpdateIfNotChangedFailsWhenResourceChanged <T>(
            Func <T, SearchRequestOptions, AccessCondition, T> createOrUpdateFunc,
            Func <T> newResourceDefinition,
            Func <T, T> mutateResourceDefinition)
            where T : IResourceWithETag
        {
            Func <T, AccessCondition, T> createOrUpdate = (a, b) => createOrUpdateFunc(a, null, b);
            var createdResource = createOrUpdate(newResourceDefinition(), AccessCondition.GenerateEmptyCondition());
            var mutatedResource = mutateResourceDefinition(createdResource);
            var updatedResource = createOrUpdate(mutatedResource, AccessCondition.GenerateEmptyCondition());

            SearchAssert.ThrowsCloudException(
                () => createOrUpdate(updatedResource, AccessCondition.IfNotChanged(createdResource)),
                e => e.IsAccessConditionFailed());

            Assert.NotEmpty(createdResource.ETag);
            Assert.NotEmpty(updatedResource.ETag);
            Assert.NotEqual(createdResource.ETag, updatedResource.ETag);
        }
        public void IfNotChangedThrowsOnNullETag()
        {
            IResourceWithETag aResourceWithETag = new AResourceWithETag();

            Assert.Throws <ArgumentNullException>(() => AccessCondition.IfNotChanged(aResourceWithETag));
        }
 public void IfNotChangedThrowsOnNullResource()
 {
     Assert.Throws <ArgumentNullException>(() => AccessCondition.IfNotChanged(null));
 }
        private async Task EnableSynonymsInCombinedIndex(ISearchServiceClient serviceClient)
        {
            const int maxTries = 3;

            for (var i = 0; i < maxTries; ++i)
            {
                try
                {
                    var index = await serviceClient.Indexes.GetAsync(SearchConstants.CombinedIndexName);

                    index.Fields.First(f => f.Name == "courseName").SynonymMaps        = new[] { SearchConstants.CourseSynonymMapName };
                    index.Fields.First(f => f.Name == "courseDescription").SynonymMaps = new[] { SearchConstants.CourseSynonymMapName };

                    // The IfNotChanged condition ensures that the index is updated only if the ETags match.
                    await serviceClient.Indexes.CreateOrUpdateAsync(index, accessCondition : AccessCondition.IfNotChanged(index));

                    break;
                }
                catch (CloudException e) when(e.IsAccessConditionFailed())
                {
                    Console.WriteLine($"Index update failed : {e.Message}. Attempt({i}/{maxTries}).\n");
                }
            }
        }
Example #10
0
        // This sample shows how ETags work by performing conditional updates and deletes
        // on an Azure Search index.
        static void Main(string[] args)
        {
            IConfigurationBuilder builder       = new ConfigurationBuilder().AddJsonFile("appsettings.json");
            IConfigurationRoot    configuration = builder.Build();

            SearchServiceClient serviceClient = CreateSearchServiceClient(configuration);

            Console.WriteLine("Deleting index...\n");
            DeleteTestIndexIfExists(serviceClient);

            // Every top-level resource in Azure Search has an associated ETag that keeps track of which version
            // of the resource you're working on. When you first create a resource such as an index, its ETag is
            // empty.
            Index index = DefineTestIndex();

            Console.WriteLine(
                $"Test index hasn't been created yet, so its ETag should be blank. ETag: '{index.ETag}'");

            // Once the resource exists in Azure Search, its ETag will be populated. Make sure to use the object
            // returned by the SearchServiceClient! Otherwise, you will still have the old object with the
            // blank ETag.
            Console.WriteLine("Creating index...\n");
            index = serviceClient.Indexes.Create(index);

            Console.WriteLine($"Test index created; Its ETag should be populated. ETag: '{index.ETag}'");

            // ETags let you do some useful things you couldn't do otherwise. For example, by using an If-Match
            // condition, we can update an index using CreateOrUpdate and be guaranteed that the update will only
            // succeed if the index already exists.
            index.Fields.Add(new Field("name", AnalyzerName.EnMicrosoft));
            index =
                serviceClient.Indexes.CreateOrUpdate(
                    index,
                    accessCondition: AccessCondition.GenerateIfExistsCondition());

            Console.WriteLine(
                $"Test index updated; Its ETag should have changed since it was created. ETag: '{index.ETag}'");

            // More importantly, ETags protect you from concurrent updates to the same resource. If another
            // client tries to update the resource, it will fail as long as all clients are using the right
            // access conditions.
            Index indexForClient1 = index;
            Index indexForClient2 = serviceClient.Indexes.Get("test");

            Console.WriteLine("Simulating concurrent update. To start, both clients see the same ETag.");
            Console.WriteLine($"Client 1 ETag: '{indexForClient1.ETag}' Client 2 ETag: '{indexForClient2.ETag}'");

            // Client 1 successfully updates the index.
            indexForClient1.Fields.Add(new Field("a", DataType.Int32));
            indexForClient1 =
                serviceClient.Indexes.CreateOrUpdate(
                    indexForClient1,
                    accessCondition: AccessCondition.IfNotChanged(indexForClient1));

            Console.WriteLine($"Test index updated by client 1; ETag: '{indexForClient1.ETag}'");

            // Client 2 tries to update the index, but fails, thanks to the ETag check.
            try
            {
                indexForClient2.Fields.Add(new Field("b", DataType.Boolean));
                serviceClient.Indexes.CreateOrUpdate(
                    indexForClient2,
                    accessCondition: AccessCondition.IfNotChanged(indexForClient2));

                Console.WriteLine("Whoops; This shouldn't happen");
                Environment.Exit(1);
            }
            catch (CloudException e) when(e.IsAccessConditionFailed())
            {
                Console.WriteLine("Client 2 failed to update the index, as expected.");
            }

            // You can also use access conditions with Delete operations. For example, you can implement an
            // atomic version of the DeleteTestIndexIfExists method from this sample like this:
            Console.WriteLine("Deleting index...\n");
            serviceClient.Indexes.Delete("test", accessCondition: AccessCondition.GenerateIfExistsCondition());

            // This is slightly better than using the Exists method since it makes only one round trip to
            // Azure Search instead of potentially two. It also avoids an extra Delete request in cases where
            // the resource is deleted concurrently, but this doesn't matter much since resource deletion in
            // Azure Search is idempotent.

            // And we're done! Bye!
            Console.WriteLine("Complete.  Press any key to end application...\n");
            Console.ReadKey();
        }