private static ICrmSubscriptionMessage Create(string messageBody, BrokeredMessage message)
        {
            Dictionary <string, string> jsonDictionary = JsonConvert.DeserializeObject <Dictionary <string, string> >(messageBody);

            if (!jsonDictionary.ContainsKey("MessageName"))
            {
                ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Unexpected message format. MessageId: {0} ", message.MessageId));
                return(null);
            }

            switch (jsonDictionary["MessageName"])
            {
            case "MetadataChange":
                NotificationUpdateManager.Instance.MetadataDirty = true;
                return(MetadataMessage.DeserializeMessage(messageBody, message));

            case "Create":
            case "Update":
            case "Delete":
                return(EntityRecordMessage.DeserializeMessage(messageBody, message));

            case "AssociateEntities":
            case "DisassociateEntities":
                return(AssociateDisassociateMessage.DeserializeMessage(messageBody, message));

            default:
                ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Unexpected message type: {0} ", jsonDictionary["MessageName"]));
                return(null);
            }
        }
        /// <summary>
        /// Pushes CrmSubscriptionMessages into the cache
        /// </summary>
        /// <param name="crmSubscriptionMessage">Message to push into the cache</param>
        /// <param name="isSearchIndexInvalidationMessage">Whther to update message from search subscription</param>
        // TODO perf might require us to keep a table in memory for lookup and access cache only to insert
        internal void UpdateNotificationMessageTable(ICrmSubscriptionMessage crmSubscriptionMessage, bool isSearchIndexInvalidationMessage = false)
        {
            if (crmSubscriptionMessage is MetadataMessage)
            {
                //When New Views are added which is a metadata change we Refresh Search Index Enabled entity List
                WebAppConfigurationProvider.GetPortalEntityList();
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Found a MetaData Change {0} in messageId: {1}.", crmSubscriptionMessage.MessageName, crmSubscriptionMessage.MessageId));
                lock (metadataFlagLock)
                {
                    this.MetadataDirtyEntry = true;
                }
                return;
            }
            EntityRecordMessage message = crmSubscriptionMessage as EntityRecordMessage;

            portalUsedEntities = WebAppConfigurationProvider.PortalUsedEntities;

            //Filter's out Entities Not Used in Portal
            if (message != null && portalUsedEntities.ContainsKey(message.EntityName))
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Pushing MessageId: {0} CRMSubscriptionMessage with entity: {1} and message name: {2} into the Cache.", message.MessageId, message.EntityName, message.MessageName));
                var entityKey = string.Format(EntityKey, message.EntityName,
                                              isSearchIndexInvalidationMessage ? FromSearchSubscription : FromCacheSubscription);
                if (!this.DirtyTable.TryAdd(entityKey, new EntityInvalidationMessageAndType(message, isSearchIndexInvalidationMessage)))
                {
                    EntityInvalidationMessageAndType val = null;
                    var success = this.DirtyTable.TryGetValue(message.EntityName, out val);
                    ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Dirty Table already contains entity: {0} and message name: {1} in the Cache with MessageId: {2}. Dropping MessageId: {3} ", message.EntityName, message.MessageName, success ? val.Message.MessageId : Guid.Empty, message.MessageId));
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Deserialize the BrokeredMessage message body into a EntityRecordMessage
        /// </summary>
        /// <param name="message">BrokeredMessage message body</param>
        /// <param name="brokeredMessage">BrokeredMessage message</param>
        /// <returns>ICrmSubscriptionMessage</returns>
        internal static ICrmSubscriptionMessage DeserializeMessage(string message, BrokeredMessage brokeredMessage)
        {
            EntityRecordMessage entityRecordMessage = (EntityRecordMessage)CrmSubscriptionMessage.DeserializeMessage(message, typeof(EntityRecordMessage));

            if (entityRecordMessage != null && entityRecordMessage.ValidMessage)
            {
                entityRecordMessage.AppendProperties(brokeredMessage);
                return(entityRecordMessage);
            }

            return(null);
        }
        /// <summary>
        /// Converts a ChangedItem to a protal cache message
        /// </summary>
        /// <param name="changedItem">ChangedItem to convert</param>
        /// <param name="entityRecordMessage">EntityRecordMessage with the corresponding entityName</param>
        /// <returns>Portal cache message converted from ChangedItem</returns>
        private PluginMessage CreateMessageForRemovedOrDeletedItem(RemovedOrDeletedItem changedItem, EntityRecordMessage entityRecordMessage)
        {
            if (changedItem == null)
            {
                return(null);
            }

            PluginMessage message;
            AssociateDisassociateMessage associateDisassociateMessage = entityRecordMessage as AssociateDisassociateMessage;

            ADXTrace.Instance.TraceWarning(TraceCategory.Application, string.Format("Converting ChangedItem/Deleted with EntityName: {0} and Type:{1} to Portal Cache Message", changedItem.RemovedItem.LogicalName, changedItem.Type.ToString()));

            if (associateDisassociateMessage == null || changedItem.RemovedItem.LogicalName == "adx_webpageaccesscontrolrule_webrole")
            {
                message = new PluginMessage
                {
                    MessageName = Constants.RemovedOrDeleted,
                    Target      = new PluginMessageEntityReference
                    {
                        Name        = null,
                        Id          = changedItem.RemovedItem.Id,
                        LogicalName = changedItem.RemovedItem.LogicalName,
                    },
                };
            }
            else
            {
                message = new PluginMessage
                {
                    MessageName = Constants.Disassociate,
                    Target      = new PluginMessageEntityReference
                    {
                        // Special Handling : We want this information to pass to adx code for dissociate and message schema is fixed / nothing can be added, this name/guid would have been null/empty else .
                        Name        = associateDisassociateMessage.EntityName,
                        Id          = changedItem.RemovedItem.Id,
                        LogicalName = associateDisassociateMessage.RelatedEntity1Name,
                    },
                    RelatedEntities = new List <PluginMessageEntityReference>
                    {
                        new PluginMessageEntityReference
                        {
                            Name        = null,
                            Id          = Guid.Empty,
                            LogicalName = associateDisassociateMessage.RelatedEntity2Name,
                        }
                    },
                    Relationship = new PluginMessageRelationship
                    {
                        PrimaryEntityRole = null,
                        SchemaName        = associateDisassociateMessage.RelationshipName,
                    },
                };
            }
            return(message);
        }
        /// <summary>
        /// Converts a ChangedItem to a protal cache message
        /// </summary>
        /// <param name="changedItem">ChangedItem to convert</param>
        /// <param name="entityRecordMessage">EntityRecordMessage with the corresponding entityName</param>
        /// <returns>Portal cache message converted from ChangedItem</returns>
        private PluginMessage CreateMessageForNewOrUpdatedItem(NewOrUpdatedItem changedItem, EntityRecordMessage entityRecordMessage)
        {
            if (changedItem == null || entityRecordMessage == null)
            {
                return(null);
            }

            PluginMessage message;
            AssociateDisassociateMessage associateDisassociateMessage = entityRecordMessage as AssociateDisassociateMessage;
            string name = this.TryGetTargetName(changedItem.NewOrUpdatedEntity);

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Converting ChangedItem with EntityName: {0} and Type:{1} to Portal Cache Message ", changedItem.NewOrUpdatedEntity.LogicalName, changedItem.Type.ToString()));

            if (associateDisassociateMessage == null || changedItem.NewOrUpdatedEntity.LogicalName == "adx_webpageaccesscontrolrule_webrole")
            {
                message = new PluginMessage
                {
                    MessageName = Constants.CreatedOrUpdated,
                    Target      = new PluginMessageEntityReference
                    {
                        Name        = name,
                        Id          = changedItem.NewOrUpdatedEntity.Id,
                        LogicalName = changedItem.NewOrUpdatedEntity.LogicalName,
                    },
                    RelatedEntities = null,
                    Relationship    = null,
                };
            }
            else
            {
                message = new PluginMessage
                {
                    MessageName = Constants.Associate,
                    Target      = new PluginMessageEntityReference
                    {
                        Name = name,
                        Id   = (Guid)changedItem.NewOrUpdatedEntity.Attributes
                               [
                            CrmChangeTrackingManager.Instance.TryGetPrimaryKey(associateDisassociateMessage.RelatedEntity1Name)
                               ],
                        LogicalName = associateDisassociateMessage.RelatedEntity1Name,
                    },
                    RelatedEntities = new List <PluginMessageEntityReference>
                    {
                        new PluginMessageEntityReference
                        {
                            Name = null,
                            Id   = (Guid)changedItem.NewOrUpdatedEntity.Attributes
                                   [
                                CrmChangeTrackingManager.Instance.TryGetPrimaryKey(associateDisassociateMessage.RelatedEntity2Name)
                                   ],
                            LogicalName = associateDisassociateMessage.RelatedEntity2Name,
                        }
                    },
                    Relationship = new PluginMessageRelationship
                    {
                        PrimaryEntityRole = null,
                        SchemaName        = associateDisassociateMessage.RelationshipName,
                    },
                };
            }

            return(message);
        }