public ConflictRule(string fullEventName, ConflictTypes conflictType) { ClientsRules = new Dictionary<string, bool>(); FullEventName = fullEventName; ConflictType = conflictType; UnsolvedClients = new List<string>(); Funnel = new Dictionary<string, int>(); OrderedFunnelClients = new List<string>(); Solved = false; }
public NewRuleViewModel(ApplicationViewModel appViewModel, ExistingRuleViewModel basedOnRule) : base(appViewModel) { m_basedOnRule = basedOnRule; SessionGroupUniqueId = appViewModel.SessionGroupUniqueId; if (m_basedOnRule != null) { SelectedSession = Sessions.FirstOrDefault(x => x.UniqueId.Equals(m_basedOnRule.ScopeId)); SelectedSource = Sources.FirstOrDefault(x => x.UniqueId.Equals(m_basedOnRule.SourceId)); SelectedConflictType = ConflictTypes.FirstOrDefault(x => x.ReferenceName.Equals(m_basedOnRule.ConflictType.ReferenceName)); Scope = m_basedOnRule.Scope; Description = m_basedOnRule.Description; SelectedResolutionAction = ResolutionActions.FirstOrDefault(x => x.ReferenceName.Equals(m_basedOnRule.ResolutionAction.ReferenceName)); } else { SelectedSession = Sessions.FirstOrDefault(); Scope = string.Empty; } }
/// <summary> /// Create values for SynchronizationImportHierarchyChange. /// </summary> /// <param name="serverId">server id.</param> /// <param name="folderIdIndex">Folder id index.</param> /// <param name="parentFolderHandleIndex">Parent folder handle index.</param> /// <param name="folderId">Folder id.</param> /// <param name="conflictType">Conflict type </param> /// <returns>Return the constructed hierarchy values.</returns> private TaggedPropertyValue[] CreateSampleHierarchyValues(int serverId, int folderIdIndex, int parentFolderHandleIndex, out ulong folderId, ConflictTypes conflictType) { folderId = 0; TaggedPropertyValue[] hierarchyValues = new TaggedPropertyValue[6]; TaggedPropertyValue propertyValue = new TaggedPropertyValue(); byte[] currentChangeNumber = new byte[6]; // PidTagParentSourceKey equal to the PidTagSourceKey of the parent folder propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E1, 0x0102) }; Sequence<string> propertyTag = new Sequence<string>("PidTagSourceKey"); this.GetPropertiesSpecific(serverId, parentFolderHandleIndex, propertyTag); propertyValue.Value = this.propertyValuesSpecific["PidTagSourceKey"]; hierarchyValues[0] = propertyValue; if (conflictType == ConflictTypes.NONE) { // Whether the hierarchy already exists. if (this.objectIdContainer.ContainsKey(folderIdIndex)) { // Construct PidTagSourceKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E0, 0x0102) }; byte[] sampleForPidTagSourceKey = this.propertyValuesSpecific["PidTagSourceKey"]; propertyValue.Value = sampleForPidTagSourceKey; hierarchyValues[1] = propertyValue; folderId = this.objectIdContainer[folderIdIndex]; // Construct PidTagLastModificationTime value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x3008, 0x0040) }; byte[] sampleForPidTagLastModificationTime = BitConverter.GetBytes(DateTime.Now.ToFileTimeUtc()); propertyValue.Value = sampleForPidTagLastModificationTime; hierarchyValues[2] = propertyValue; // Construct PidTagChangeKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E2, 0x0102) }; byte[] sampleForPidTagChangeKey = this.propertyValuesSpecific["PidTagChangeKey"]; // Modify ChangeKey to generate a new ChangeKey. byte[] temp = new byte[4]; Array.Copy(sampleForPidTagChangeKey, sampleForPidTagChangeKey.Length - 4, temp, 0, 4); Array.Reverse(temp); int add = BitConverter.ToInt32(temp, 0); // Modify the changeNumber to a newer version. add++; temp = BitConverter.GetBytes(add); Array.Reverse(temp); Array.Copy(temp, 0, sampleForPidTagChangeKey, sampleForPidTagChangeKey.Length - 4, 4); propertyValue.Value = sampleForPidTagChangeKey; hierarchyValues[3] = propertyValue; // Construct PidTagPredecessorChangeList value propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E3, 0x0102) }; byte[] sampleForPidTagPredecessorChangeList = new byte[this.propertyValuesSpecific["PidTagPredecessorChangeList"].Length + sampleForPidTagChangeKey.Length]; Array.Copy(this.propertyValuesSpecific["PidTagPredecessorChangeList"], 0, sampleForPidTagPredecessorChangeList, 0, this.propertyValuesSpecific["PidTagPredecessorChangeList"].Length); Array.Copy(sampleForPidTagChangeKey, 0, sampleForPidTagPredecessorChangeList, this.propertyValuesSpecific["PidTagPredecessorChangeList"].Length, sampleForPidTagChangeKey.Length); propertyValue.Value = sampleForPidTagPredecessorChangeList; hierarchyValues[4] = propertyValue; } else if (folderIdIndex == 0) { // Get a local id from the id set given by server. byte[] sub = new byte[4]; byte[] currentLocalId = this.localId; Array.Copy(currentLocalId, 2, sub, 0, currentLocalId.Length - 2); Array.Reverse(sub); int totalNum = BitConverter.ToInt32(sub, 0); totalNum += this.localIdOffSet; sub = BitConverter.GetBytes(totalNum); Array.Reverse(sub); Array.Copy(sub, 0, currentLocalId, 2, currentLocalId.Length - 2); this.localIdOffSet++; // Construct PidTagSourceKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E0, 0x0102) }; byte[] sampleForPidTagSourceKey = new byte[24]; int length = 0; int index = 0; // The combination of first two bytes indicates the length of value field. length = (short)(this.serverReplicaGuid.ToByteArray().Length + currentLocalId.Length); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagSourceKey, 0, sizeof(short)); index += sizeof(short); Array.Copy(this.serverReplicaGuid.ToByteArray(), 0, sampleForPidTagSourceKey, index, this.serverReplicaGuid.ToByteArray().Length); index += this.serverReplicaGuid.ToByteArray().Length; Array.Copy(currentLocalId, 0, sampleForPidTagSourceKey, index, currentLocalId.Length); Array.Copy(currentLocalId, 0, currentChangeNumber, 0, currentLocalId.Length); propertyValue.Value = sampleForPidTagSourceKey; hierarchyValues[1] = propertyValue; // Convert long term id to id . LongTermId longTermId = new LongTermId { DatabaseGuid = this.serverReplicaGuid.ToByteArray(), GlobalCounter = currentLocalId }; folderId = this.GetIdFromLongTerm(serverId, longTermId); // Construct PidTagLastModificationTime value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x3008, 0x0040) }; byte[] sampleForPidTagLastModificationTime = BitConverter.GetBytes(DateTime.Now.ToFileTimeUtc()); propertyValue.Value = sampleForPidTagLastModificationTime; hierarchyValues[2] = propertyValue; // Construct PidTagChangeKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E2, 0x0102) }; byte[] sampleForPidTagChangeKey = new byte[24]; index = 0; length = 0; length = (short)GidLength; // The combination of first two bytes indicates the length of value field. Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagChangeKey, 0, sizeof(short)); index += sizeof(short); Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagChangeKey, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagChangeKey, index, currentChangeNumber.Length); propertyValue.Value = sampleForPidTagChangeKey; hierarchyValues[3] = propertyValue; // Construct PidTagPredecessorChangeList value propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E3, 0x0102) }; byte[] sampleForPidTagPredecessorChangeList = new byte[25]; index = 0; length = 0; length = (short)(GidLength + 1); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagPredecessorChangeList, 0, sizeof(short)); index += sizeof(short); sampleForPidTagPredecessorChangeList[2] = Convert.ToByte(this.localReplicaGuid.ToByteArray().Length + currentChangeNumber.Length); // 16 index += 1; Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagPredecessorChangeList, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagPredecessorChangeList, index, currentChangeNumber.Length); propertyValue.Value = sampleForPidTagPredecessorChangeList; hierarchyValues[4] = propertyValue; } } else { // Get a local id from the id set given by server. byte[] sub = new byte[4]; byte[] currentLocalId = this.localId; Array.Copy(currentLocalId, 2, sub, 0, currentLocalId.Length - 2); Array.Reverse(sub); int totalNum = BitConverter.ToInt32(sub, 0); totalNum += this.localIdOffSet; sub = BitConverter.GetBytes(totalNum); Array.Reverse(sub); Array.Copy(sub, 0, currentLocalId, 2, currentLocalId.Length - 2); this.localIdOffSet++; // Construct PidTagSourceKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E0, 0x0102) }; byte[] sampleForPidTagSourceKey = new byte[24]; int length = 0; int index = 0; // The combination of first two bytes indicates the length of value field. length = (short)(this.serverReplicaGuid.ToByteArray().Length + currentLocalId.Length); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagSourceKey, 0, sizeof(short)); index += sizeof(short); Array.Copy(this.serverReplicaGuid.ToByteArray(), 0, sampleForPidTagSourceKey, index, this.serverReplicaGuid.ToByteArray().Length); index += this.serverReplicaGuid.ToByteArray().Length; Array.Copy(currentLocalId, 0, sampleForPidTagSourceKey, index, currentLocalId.Length); Array.Copy(currentLocalId, 0, currentChangeNumber, 0, currentLocalId.Length); propertyValue.Value = sampleForPidTagSourceKey; hierarchyValues[1] = propertyValue; // Convert long term id to id . LongTermId longTermId = new LongTermId { DatabaseGuid = this.serverReplicaGuid.ToByteArray(), GlobalCounter = currentLocalId }; folderId = this.GetIdFromLongTerm(serverId, longTermId); // Construct PidTagLastModificationTime value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x3008, 0x0040) }; byte[] sampleForPidTagLastModificationTime = BitConverter.GetBytes(DateTime.Now.ToFileTimeUtc()); propertyValue.Value = sampleForPidTagLastModificationTime; hierarchyValues[2] = propertyValue; // Construct PidTagChangeKey value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E2, 0x0102) }; byte[] sampleForPidTagChangeKey = new byte[24]; index = 0; length = 0; length = (short)GidLength; // The combination of first two bytes indicates the length of value field. Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagChangeKey, 0, sizeof(short)); index += sizeof(short); Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagChangeKey, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagChangeKey, index, currentChangeNumber.Length); propertyValue.Value = sampleForPidTagChangeKey; hierarchyValues[3] = propertyValue; // Construct PidTagPredecessorChangeList value propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x65E3, 0x0102) }; byte[] sampleForPidTagPredecessorChangeList; if (conflictType == ConflictTypes.AINCLUDEB) { sampleForPidTagPredecessorChangeList = new byte[25]; index = 0; length = 0; length = (short)(GidLength + 1); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagPredecessorChangeList, 0, sizeof(short)); index += sizeof(short); sampleForPidTagPredecessorChangeList[2] = Convert.ToByte(this.localReplicaGuid.ToByteArray().Length + currentChangeNumber.Length); // 16 index += 1; Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagPredecessorChangeList, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagPredecessorChangeList, index, currentChangeNumber.Length); this.lastConflictInfo.PCLB = sampleForPidTagPredecessorChangeList; sampleForPidTagPredecessorChangeList[24] += 1; this.lastConflictInfo.PCLA = sampleForPidTagPredecessorChangeList; this.lastConflictInfo.PCLXFromMath = sampleForPidTagPredecessorChangeList; this.lastConflictInfo.DetectedResult = conflictType; propertyValue.Value = sampleForPidTagPredecessorChangeList; hierarchyValues[4] = propertyValue; } else if (conflictType == ConflictTypes.BINCLUDEA) { sampleForPidTagPredecessorChangeList = new byte[25]; index = 0; length = 0; length = (short)(GidLength + 1); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagPredecessorChangeList, 0, sizeof(short)); index += sizeof(short); sampleForPidTagPredecessorChangeList[2] = Convert.ToByte(this.localReplicaGuid.ToByteArray().Length + currentChangeNumber.Length); // 16 index += 1; Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagPredecessorChangeList, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagPredecessorChangeList, index, currentChangeNumber.Length); this.lastConflictInfo.PCLB = sampleForPidTagPredecessorChangeList; this.lastConflictInfo.PCLXFromMath = sampleForPidTagPredecessorChangeList; sampleForPidTagPredecessorChangeList[24] -= 1; this.lastConflictInfo.PCLA = sampleForPidTagPredecessorChangeList; this.lastConflictInfo.DetectedResult = conflictType; propertyValue.Value = sampleForPidTagPredecessorChangeList; hierarchyValues[4] = propertyValue; } if (conflictType == ConflictTypes.CONFLICT) { // If the versions from client and server are in conflict, the value of PidTagPredecessorChangeList property in client should not include // the one in server. And the changelist value in server should not include or be equal to the one in client, which means the changelist value in client // should be different with server, just like the second example in section 4.6.2. sampleForPidTagPredecessorChangeList = new byte[25]; index = 0; length = 0; length = (short)(GidLength + 1); Array.Copy(BitConverter.GetBytes(length), 0, sampleForPidTagPredecessorChangeList, 0, sizeof(short)); index += sizeof(short); sampleForPidTagPredecessorChangeList[2] = Convert.ToByte(this.localReplicaGuid.ToByteArray().Length + currentChangeNumber.Length); // 16 index += 1; Array.Copy(this.localReplicaGuid.ToByteArray(), 0, sampleForPidTagPredecessorChangeList, index, this.localReplicaGuid.ToByteArray().Length); index += this.localReplicaGuid.ToByteArray().Length; Array.Copy(currentChangeNumber, 0, sampleForPidTagPredecessorChangeList, index, currentChangeNumber.Length); this.lastConflictInfo.PCLB = sampleForPidTagPredecessorChangeList; // The parameter change is used to save the changelist value in client. byte[] change = new byte[48]; Array.Copy(BitConverter.GetBytes(46), 0, change, 0, sizeof(short)); Array.Copy(sampleForPidTagPredecessorChangeList, 2, change, 2, 23); Array.Copy(BitConverter.GetBytes(22), 0, change, 25, sizeof(short)); // Modify the value of PidTagPredecessorChangeList property in client via adding one in GUID field and adding one in GLOBCNT field. byte[] namespaceGuidPartValue = new byte[8]; Array.Copy(sampleForPidTagPredecessorChangeList, 10, namespaceGuidPartValue, 2, namespaceGuidPartValue.Length - 2); Array.Reverse(namespaceGuidPartValue); long namespaceGuidPartValueInt = BitConverter.ToInt64(namespaceGuidPartValue, 0); namespaceGuidPartValueInt += 1; namespaceGuidPartValue = BitConverter.GetBytes(namespaceGuidPartValueInt); Array.Reverse(namespaceGuidPartValue); Array.Copy(namespaceGuidPartValue, 2, sampleForPidTagPredecessorChangeList, 10, namespaceGuidPartValue.Length - 2); Array.Copy(sampleForPidTagPredecessorChangeList, 3, change, 26, 22); change[47] += 1; this.lastConflictInfo.PCLA = change; this.lastConflictInfo.PCLXFromMath = change; this.lastConflictInfo.DetectedResult = conflictType; propertyValue.Value = change; hierarchyValues[4] = propertyValue; } } // Construct PidTagDisplayName value. propertyValue = new TaggedPropertyValue { PropertyTag = new PropertyTag(0x3001, 0x001F) }; byte[] sampleForPidTagDisplayName = new byte[Encoding.Unicode.GetByteCount("TestFolder" + "\0")]; Array.Copy( Encoding.Unicode.GetBytes("TestFolder" + "\0"), 0, sampleForPidTagDisplayName, 0, Encoding.Unicode.GetByteCount("TestFolder" + "\0")); propertyValue.Value = sampleForPidTagDisplayName; hierarchyValues[5] = propertyValue; return hierarchyValues; }
/// <summary> /// Import new folders, or changes with conflict to existing folders, into the server replica. /// </summary> /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param> /// <param name="uploadContextHandleIndex">Upload context handle.</param> /// <param name="parentFolderHandleIndex">Parent folder handle index.</param> /// <param name="properties">Properties to be set.</param> /// <param name="localFolderIdIndex">Local folder id index</param> /// <param name="folderIdIndex">The folder object id index.</param> /// <param name="conflictType">The conflict type will import.</param> /// <returns>Indicate the result of this ROP operation.</returns> public RopResult SynchronizationImportHierarchyChangeWithConflict(int serverId, int uploadContextHandleIndex, int parentFolderHandleIndex, Set<string> properties, int localFolderIdIndex, out int folderIdIndex, ConflictTypes conflictType) { // Initialize ROP data. uint uploadContextHandle = this.handleContainer[uploadContextHandleIndex]; RopResult result = RopResult.InvalidParameter; folderIdIndex = -1; ulong folderId; // Construct ROP request. RopSynchronizationImportHierarchyChangeRequest synchronizationImportHierarchyChangeRequest; // Construct the RopSynchronizationImportHierarchyChange request. synchronizationImportHierarchyChangeRequest.RopId = 0x73; synchronizationImportHierarchyChangeRequest.LogonId = 0x00; synchronizationImportHierarchyChangeRequest.InputHandleIndex = 0x00; // Get the folder property value. TaggedPropertyValue[] taggedPropertyValueArrays = new TaggedPropertyValue[properties.Count]; int index = 0; foreach (string tempProperty in properties) { taggedPropertyValueArrays[index++] = this.taggedPropertyValuesDictionary[tempProperty]; } TaggedPropertyValue[] hierarchyValues = this.CreateSampleHierarchyValues(serverId, localFolderIdIndex, parentFolderHandleIndex, out folderId, conflictType); synchronizationImportHierarchyChangeRequest.HierarchyValueCount = (ushort)hierarchyValues.Length; synchronizationImportHierarchyChangeRequest.HierarchyValues = hierarchyValues; synchronizationImportHierarchyChangeRequest.PropertyValueCount = (ushort)taggedPropertyValueArrays.Length; synchronizationImportHierarchyChangeRequest.PropertyValues = taggedPropertyValueArrays; // Send request and get response. RopSynchronizationImportHierarchyChangeResponse synchronizationImportHierarchyChangeResponse = (RopSynchronizationImportHierarchyChangeResponse)this.Process(serverId, synchronizationImportHierarchyChangeRequest, uploadContextHandle); result = (RopResult)synchronizationImportHierarchyChangeResponse.ReturnValue; if (result == RopResult.Success) { if (!this.objectIdContainer.ContainsKey(localFolderIdIndex)) { folderIdIndex = AdapterHelper.GetObjectIdIndex(); this.objectIdContainer.Add(folderIdIndex, folderId); } // Verify ROP SynchronizationImportHierarchyChange this.VerifyRopSynchronizationImportHierarchyChange(synchronizationImportHierarchyChangeResponse); } return result; }
public static RopResult SynchronizationImportHierarchyChangeWithConflict(int serverId, int uploadContextHandleIndex, int parentFolderHandleIndex, Set<string> properties, int localFolderIdIndex, out int folderIdIndex, ConflictTypes conflictType) { return SynchronizationImportHierarchyChange(serverId, uploadContextHandleIndex, parentFolderHandleIndex, properties, localFolderIdIndex, out folderIdIndex); }