Example #1
0
        private void InvalidateSearchIndex(List <OrganizationServiceCachePluginMessage> batchedPluginMessage, Dictionary <Guid, SearchIndexBuildRequest.SearchIndexInvalidationData> searchInvalidationDatum)
        {
            foreach (var message in batchedPluginMessage)
            {
                if (message.Target == null || SearchMetadataCache.Instance.SearchEnabledEntities.Contains(message.Target.LogicalName))
                {
                    SearchIndexBuildRequest.SearchIndexInvalidationData searchInvalidationData = null;

                    if (message.Target != null)
                    {
                        searchInvalidationDatum.TryGetValue(message.Target.Id, out searchInvalidationData);
                    }

                    retryPolicy.Value.ExecuteAction(() => SearchIndexBuildRequest.ProcessMessage(message, searchInvalidationData, CrmChangeTrackingManager.Instance.OrganizationServiceContext));
                }
            }
        }
Example #2
0
        private void ProcessNotification(CancellationToken cancellationToken, PluginMessageRequest request)
        {
            try
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (!WebNotificationCryptography.ValidateRequest(request.Authorization))
                {
                    WebNotificationEventSource.Log.AuthorizationValidationFailed();

                    return;
                }

                var message = this.GetMessage(request);

                if (message == null)
                {
                    WebNotificationEventSource.Log.MessageInvalid();

                    return;
                }

                CacheInvalidation.ProcessMessage(message);

                if (SearchIndexApplicableMessages.Contains(message.MessageName, MessageComparer))
                {
                    var serviceContext = CrmConfigurationManager.CreateContext();
                    SearchIndexBuildRequest.ProcessMessage(message, serviceContext: serviceContext);
                }
            }
            catch (TaskCanceledException e)
            {
                ADXTrace.Instance.TraceWarning(TraceCategory.Application, e.Message);
            }
        }
Example #3
0
        /// <summary>
        /// Posts notifications of entity changes
        /// </summary>
        /// <param name="messages">List of Notification messages</param>
        /// <param name="isMetadataChangeMessage">True if it is a metadata change notification.</param>
        /// <param name="isSearchIndexInvalidation">True for search index invlaidation and false for cache invalidation.</param>
        /// <returns></returns>
        private List <string> PostRequest(IEnumerable <PluginMessage> messages, bool isMetadataChangeMessage, bool isSearchIndexInvalidation = false)
        {
            List <string> entitiesWithSuccessfulInvalidation = new List <string>();

            try
            {
                var batchedMessages = messages
                                      .Where(mesg => mesg != null)
                                      .GroupBy(mesg => mesg.Target == null ? string.Empty : mesg.Target.LogicalName);

                foreach (var batchedmessage in batchedMessages)
                {
                    List <OrganizationServiceCachePluginMessage> batchedPluginMessage = new List <OrganizationServiceCachePluginMessage>();
                    var searchInvalidationDatum = new Dictionary <Guid, SearchIndexBuildRequest.SearchIndexInvalidationData>();

                    foreach (var changedItem in batchedmessage)
                    {
                        if (changedItem != null)
                        {
                            if (changedItem.Target != null)
                            {
                                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Posting Request for message with Entity: {0} and ChangeType: {1}", changedItem.Target.LogicalName, changedItem.MessageName));
                            }

                            var restartMessage = new ApplicationRestartPortalBusMessage();

                            // Conversion to OrganizationServiceCachePluginMessage type
                            var message = new OrganizationServiceCachePluginMessage();
                            message.MessageName     = changedItem.MessageName;
                            message.RelatedEntities = changedItem.RelatedEntities;
                            message.Relationship    = changedItem.Relationship;
                            message.Target          = changedItem.Target;

                            if (restartMessage.Validate(changedItem))
                            {
                                // The restart messages should be processed only once when the message is received from Cache subscription.
                                if (!isSearchIndexInvalidation)
                                {
                                    // restart the web application
                                    var task = restartMessage.InvokeAsync(new OwinContext()).WithCurrentCulture();
                                    task.GetAwaiter().GetResult();
                                    SearchIndexBuildRequest.ProcessMessage(message);
                                }
                            }
                            else
                            {
                                if (!isSearchIndexInvalidation && FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching) && message.Target != null && message.Target.Id != Guid.Empty)
                                {
                                    // Get relevant info for search index invalidation from content map before cache invalidation
                                    // MUST OCCUR BEFORE CACHE INVALIDATION
                                    if (!searchInvalidationDatum.ContainsKey(message.Target.Id))
                                    {
                                        searchInvalidationDatum.Add(message.Target.Id, GetSearchIndexInvalidationData(message));
                                    }
                                }
                                batchedPluginMessage.Add(message);
                            }
                        }
                        else
                        {
                            //logging
                            ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("ChangedItem Record is Null "));
                        }
                    }
                    if (batchedPluginMessage.Count > 0)
                    {
                        if (isMetadataChangeMessage)
                        {
                            // Invalidate both search index as well as cache
                            try
                            {
                                InvalidateSearchIndex(batchedPluginMessage, searchInvalidationDatum);
                            }
                            catch (Exception e)
                            {
                                // Even if exception occurs, we still need to invalidate cache, hence cathing exception here and logging error.
                                ADXTrace.Instance.TraceError(TraceCategory.Exception, e.ToString());
                            }
                            InvalidateCache(batchedPluginMessage);
                        }
                        else if (isSearchIndexInvalidation)
                        {
                            InvalidateSearchIndex(batchedPluginMessage, searchInvalidationDatum);
                        }
                        else
                        {
                            // Invalidate cache
                            InvalidateCache(batchedPluginMessage);
                        }
                    }

                    entitiesWithSuccessfulInvalidation.Add(batchedmessage.Key);
                }
                return(entitiesWithSuccessfulInvalidation);
            }
            catch (Exception e)
            {
                ADXTrace.Instance.TraceError(TraceCategory.Application, e.ToString());
                return(entitiesWithSuccessfulInvalidation);
            }
        }