public void MSOXCROPS_S11_TC06_TestRopSynchronizationImportMessageMove() { this.CheckTransportIsSupported(); this.cropsAdapter.RpcConnect( Common.GetConfigurationPropertyValue("SutComputerName", this.Site), ConnectionType.PrivateMailboxServer, Common.GetConfigurationPropertyValue("UserEssdn", this.Site), Common.GetConfigurationPropertyValue("Domain", this.Site), Common.GetConfigurationPropertyValue("AdminUserName", this.Site), Common.GetConfigurationPropertyValue("PassWord", this.Site)); // Step 1: Open folder. #region Open folder RopLogonResponse logonResponse = Logon(LogonType.Mailbox, this.userDN, out inputObjHandle); RopOpenFolderRequest openFolderRequest; RopOpenFolderResponse openFolderResponse; // Construct RopOpenFolder request. openFolderRequest.RopId = (byte)RopId.RopOpenFolder; openFolderRequest.LogonId = TestSuiteBase.LogonId; openFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; openFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1; openFolderRequest.FolderId = logonResponse.FolderIds[4]; openFolderRequest.OpenModeFlags = (byte)FolderOpenModeFlags.None; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 1: Begin to send the RopOpenFolder request."); // Send the RopOpenFolder request to the server and verify the success response. this.responseSOHs = cropsAdapter.ProcessSingleRop( openFolderRequest, this.inputObjHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); openFolderResponse = (RopOpenFolderResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, openFolderResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); // Get the handle of opened folder, which will be used as input handle in RopCreateFolder. uint openedFolderHandle = responseSOHs[0][openFolderResponse.OutputHandleIndex]; #endregion // Step 2: Create the first subfolder in opened folder. #region Create the first subfolder RopCreateFolderRequest createFolderRequest; RopCreateFolderResponse createFolderResponse; // Construct RopCreateFolder request. createFolderRequest.RopId = (byte)RopId.RopCreateFolder; createFolderRequest.LogonId = TestSuiteBase.LogonId; createFolderRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; createFolderRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1; createFolderRequest.FolderType = (byte)FolderType.Genericfolder; createFolderRequest.UseUnicodeStrings = Convert.ToByte(TestSuiteBase.Zero); createFolderRequest.OpenExisting = TestSuiteBase.NonZero; createFolderRequest.Reserved = TestSuiteBase.Reserved; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0"); createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 2: Begin to send the RopCreateFolder request."); // Send the RopCreateFolder request to the server and verify the success response. this.responseSOHs = cropsAdapter.ProcessSingleRop( createFolderRequest, openedFolderHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); createFolderResponse = (RopCreateFolderResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, createFolderResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); uint targetFolderHandle = responseSOHs[0][createFolderResponse.OutputHandleIndex]; #endregion // Step 3: Create the second subfolder in opened folder #region Create the second subfolder RopCreateFolderResponse createSecondFolderResponse; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0"); createFolderRequest.Comment = Encoding.ASCII.GetBytes(TestSuiteBase.DisplayNameAndCommentForNonSearchFolder + "\0"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 3: Begin to send the RopCreateFolder request."); // Send the RopCreateFolder request to create the second subfolder. this.responseSOHs = cropsAdapter.ProcessSingleRop( createFolderRequest, openedFolderHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); createSecondFolderResponse = (RopCreateFolderResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, createFolderResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); uint secondFolderHandle = responseSOHs[0][createSecondFolderResponse.OutputHandleIndex]; #endregion // Step 4: Configure a synchronization upload context #region Configure a synchronization upload context RopSynchronizationOpenCollectorRequest synchronizationOpenCollectorMsgRequest; RopSynchronizationOpenCollectorResponse synchronizationOpenCollectorMsgResponse; // Construct RopSynchronizationOpenCollector request. synchronizationOpenCollectorMsgRequest.RopId = (byte)RopId.RopSynchronizationOpenCollector; synchronizationOpenCollectorMsgRequest.LogonId = TestSuiteBase.LogonId; synchronizationOpenCollectorMsgRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; synchronizationOpenCollectorMsgRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1; synchronizationOpenCollectorMsgRequest.IsContentsCollector = TestSuiteBase.NonZero; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 4: Begin to send the RopSynchronizationOpenCollector request."); // Send the RopSynchronizationOpenCollector request to the server and verify the success response. this.responseSOHs = cropsAdapter.ProcessSingleRop( synchronizationOpenCollectorMsgRequest, targetFolderHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); synchronizationOpenCollectorMsgResponse = (RopSynchronizationOpenCollectorResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, synchronizationOpenCollectorMsgResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); uint synchronizationUploadContextHandleMsg = responseSOHs[0][synchronizationOpenCollectorMsgResponse.OutputHandleIndex]; #endregion // Step 5: Send the RopSynchronizationImportMessageChange request to import new messages // or full changes to existing messages into the server replica. #region RopSynchronizationImportMessageChange RopSynchronizationImportMessageChangeRequest synchronizationImportMessageChangeRequest; RopSynchronizationImportMessageChangeResponse synchronizationImportMessageChangeResponse; // Call CreateSamplePropertyValues method to create property value samples. TaggedPropertyValue[] propertyValues = this.CreateSamplePropertyValues(); // Construct the RopSynchronizationImportMessageChange request. synchronizationImportMessageChangeRequest.RopId = (byte)RopId.RopSynchronizationImportMessageChange; synchronizationImportMessageChangeRequest.LogonId = TestSuiteBase.LogonId; synchronizationImportMessageChangeRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; synchronizationImportMessageChangeRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1; synchronizationImportMessageChangeRequest.ImportFlag = (byte)ImportFlag.Normal; synchronizationImportMessageChangeRequest.PropertyValueCount = (ushort)propertyValues.Length; synchronizationImportMessageChangeRequest.PropertyValues = propertyValues; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 5: Begin to send the RopSynchronizationImportMessageChange request."); // Send the RopSynchronizationImportMessageChange request and get its output handle. this.responseSOHs = cropsAdapter.ProcessSingleRop( synchronizationImportMessageChangeRequest, synchronizationUploadContextHandleMsg, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); synchronizationImportMessageChangeResponse = (RopSynchronizationImportMessageChangeResponse)response; uint targetMessageHandle = responseSOHs[0][synchronizationImportMessageChangeResponse.OutputHandleIndex]; #endregion // Step 6: Save message. #region Save message RopSaveChangesMessageRequest saveChangesMessageRequest; RopSaveChangesMessageResponse saveChangesMessageResponse; // Construct the RopSaveChangesMessage request. saveChangesMessageRequest.RopId = (byte)RopId.RopSaveChangesMessage; saveChangesMessageRequest.LogonId = TestSuiteBase.LogonId; saveChangesMessageRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; saveChangesMessageRequest.ResponseHandleIndex = TestSuiteBase.ResponseHandleIndex1; saveChangesMessageRequest.SaveFlags = (byte)SaveFlags.ForceSave; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 6: Begin to send the RopSaveChangesMessage request."); // Send the RopSaveChangesMessage request to the server and verify the success response. this.responseSOHs = cropsAdapter.ProcessSingleRop( saveChangesMessageRequest, targetMessageHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); saveChangesMessageResponse = (RopSaveChangesMessageResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, saveChangesMessageResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)."); #endregion // Step 7: Send the RopSynchronizationImportMessageMove request and verify the response. #region RopSynchronizationImportMessageMove response. RopSynchronizationImportMessageMoveRequest importMessageMoveRequest = new RopSynchronizationImportMessageMoveRequest(); RopSynchronizationImportMessageMoveResponse importMessageMoveResponse; // Construct the RopSynchronizationImportMessageMove request. #region Construct the RopSynchronizationImportMessageMove request importMessageMoveRequest.RopId = (byte)RopId.RopSynchronizationImportMessageMove; importMessageMoveRequest.LogonId = TestSuiteBase.LogonId; importMessageMoveRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; importMessageMoveRequest.SourceFolderIdSize = 22; byte[] value = new byte[22]; // Send the RopLongTermIdFromId request to convert the short-term ID into a long-term ID. #region convert the short-term ID into the long-term ID RopLongTermIdFromIdRequest ropLongTermIdFromIdRequest = new RopLongTermIdFromIdRequest(); RopLongTermIdFromIdResponse ropLongTermIdFromIdResponse; // Construct the RopLongTermIdFromId request. ropLongTermIdFromIdRequest.RopId = (byte)RopId.RopLongTermIdFromId; ropLongTermIdFromIdRequest.LogonId = TestSuiteBase.LogonId; ropLongTermIdFromIdRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; ropLongTermIdFromIdRequest.ObjectId = createFolderResponse.FolderId; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 7: Begin to send the RopSaveChangesMessage request."); // Send the RopLongTermIdFromId request to convert the short-term ID into a long-term ID. this.responseSOHs = cropsAdapter.ProcessSingleRop( ropLongTermIdFromIdRequest, this.inputObjHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); ropLongTermIdFromIdResponse = (RopLongTermIdFromIdResponse)response; Array.Copy(ropLongTermIdFromIdResponse.LongTermId.DatabaseGuid, 0, value, 0, 16); Array.Copy(ropLongTermIdFromIdResponse.LongTermId.GlobalCounter, 0, value, 16, 6); #endregion importMessageMoveRequest.SourceFolderId = value; importMessageMoveRequest.SourceMessageIdSize = 22; byte[] value1 = new byte[22]; Array.Copy(propertyValues[0].Value, 2, value1, 0, 22); importMessageMoveRequest.SourceMessageId = value1; byte[] value3 = new byte[22]; // Send the RopGetLocalReplicaIds to reserve a range of IDs to be used by a local replica. #region Reserve a range of IDs RopGetLocalReplicaIdsRequest ropGetLocalReplicaIdsRequest; RopGetLocalReplicaIdsResponse ropGetLocalReplicaIdsResponse; // Construct the RopGetLocalReplicaIds request. ropGetLocalReplicaIdsRequest.IdCount = 2; ropGetLocalReplicaIdsRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; ropGetLocalReplicaIdsRequest.LogonId = TestSuiteBase.LogonId; ropGetLocalReplicaIdsRequest.RopId = (byte)RopId.RopGetLocalReplicaIds; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 7: Begin to send the RopGetLocalReplicaIds request."); // Send the RopGetLocalReplicaIds to reserve a range of IDs to be used by a local replica. this.responseSOHs = cropsAdapter.ProcessSingleRop( ropGetLocalReplicaIdsRequest, this.inputObjHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); ropGetLocalReplicaIdsResponse = (RopGetLocalReplicaIdsResponse)response; Array.Copy(ropGetLocalReplicaIdsResponse.ReplGuid, 0, value3, 0, 16); Array.Copy(ropGetLocalReplicaIdsResponse.GlobalCount, 0, value3, 16, 6); #endregion importMessageMoveRequest.DestinationMessageIdSize = 22; importMessageMoveRequest.DestinationMessageId = value3; // PidTagChangeKey byte[] bytesForChangeNumber = new byte[20]; byte[] guid = Guid.NewGuid().ToByteArray(); Array.Copy(guid, 0, bytesForChangeNumber, 0, 16); importMessageMoveRequest.ChangeNumberSize = 20; importMessageMoveRequest.ChangeNumber = bytesForChangeNumber; importMessageMoveRequest.PredecessorChangeListSize = 23; byte[] bytesForPredecessorChangeList = { 0x16, 0x19, 0xD7, 0xFB, 0x0F, 0x06, 0x16, 0xA1, 0x41, 0xBF, 0xF6, 0x91, 0xC7, 0x63, 0xDA, 0xA8, 0x66, 0x00, 0x00, 0x00, 0x78, 0x4D, 0x1C }; importMessageMoveRequest.PredecessorChangeList = bytesForPredecessorChangeList; // Configure a synchronization upload context #region Configure a synchronization upload context RopSynchronizationOpenCollectorRequest synchronizationOpenCollectorRequest; RopSynchronizationOpenCollectorResponse synchronizationOpenCollectorResponse; // Construct the RopSynchronizationOpenCollector request. synchronizationOpenCollectorRequest.RopId = (byte)RopId.RopSynchronizationOpenCollector; synchronizationOpenCollectorRequest.LogonId = TestSuiteBase.LogonId; synchronizationOpenCollectorRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex0; synchronizationOpenCollectorRequest.OutputHandleIndex = TestSuiteBase.OutputHandleIndex1; synchronizationOpenCollectorRequest.IsContentsCollector = TestSuiteBase.NonZero; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 7: Begin to send the RopSynchronizationOpenCollector request."); // Send the RopSynchronizationOpenCollector request to the server and verify the success response. this.responseSOHs = cropsAdapter.ProcessSingleRop( synchronizationOpenCollectorRequest, secondFolderHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); synchronizationOpenCollectorResponse = (RopSynchronizationOpenCollectorResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, synchronizationOpenCollectorResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); uint synchronizationUploadContextHandle = responseSOHs[0][synchronizationOpenCollectorResponse.OutputHandleIndex]; #endregion #endregion // RopSynchronizationImportMessageMove success response. #region RopSynchronizationImportMessageMove success response // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 7: Begin to send the RopSynchronizationImportMessageMove request to invoke success response."); this.responseSOHs = cropsAdapter.ProcessSingleRop( importMessageMoveRequest, synchronizationUploadContextHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); importMessageMoveResponse = (RopSynchronizationImportMessageMoveResponse)response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, importMessageMoveResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0 (success)"); #endregion // RopSynchronizationImportMessageMove failure response. #region RopSynchronizationImportMessageMove failure response importMessageMoveRequest.InputHandleIndex = TestSuiteBase.InputHandleIndex1; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Step 7: Begin to send the RopSynchronizationImportMessageMove request to invoke failure response."); this.responseSOHs = cropsAdapter.ProcessSingleRop( importMessageMoveRequest, synchronizationUploadContextHandle, ref this.response, ref this.rawData, RopResponseType.FailureResponse); #endregion #endregion }
/// <summary> /// Imports information about moving a message between two existing folders within the same mailbox. /// </summary> /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param> /// <param name="synchronizationUploadContextHandleIndex">The index of the synchronization upload context configured for collecting changes to the contents of the message move destination folder.</param> /// <param name="sourceFolderIdIndex">The index of the source folder id in object id container.</param> /// <param name="destinationFolderIdIndex">The index of the destination folder id in object id container.</param> /// <param name="sourceMessageIdIndex">The index of source message id in object id container.</param> /// <param name="sourceFolderHandleIndex">The index of source folder handle in handleContainer.</param> /// <param name="destinationFolderHandleIndex">The index of destination folder handle in handle container.</param> /// <param name="inewerClientChange">If the client has a newer message.</param> /// <param name="iolderversion">If the server have an older version of a message .</param> /// <param name="icnpc">Verify if the change number has been used.</param> /// <returns>Indicate the result of this ROP operation.</returns> public RopResult SynchronizationImportMessageMove(int serverId, int synchronizationUploadContextHandleIndex, int sourceFolderIdIndex, int destinationFolderIdIndex, int sourceMessageIdIndex, int sourceFolderHandleIndex, int destinationFolderHandleIndex, bool inewerClientChange, out bool iolderversion, out bool icnpc) { // Initialize return value. iolderversion = false; icnpc = true; RopResult result = RopResult.InvalidParameter; uint synchronizationUploadContextHandle = this.handleContainer[synchronizationUploadContextHandleIndex]; uint sourceFolderHandle = this.handleContainer[sourceFolderHandleIndex]; ulong sourceFID = this.objectIdContainer[sourceFolderIdIndex]; ulong sourceMID = this.objectIdContainer[sourceMessageIdIndex]; // Construct the RopSynchronizationImportMessageMove request. RopSynchronizationImportMessageMoveRequest importMessageMoveRequest = new RopSynchronizationImportMessageMoveRequest { RopId = 0x78, LogonId = 0x00, InputHandleIndex = 0x00 }; // Get source folder id. byte[] fidLongTermId = this.GetLongTermIdByte(serverId, sourceFID); importMessageMoveRequest.SourceFolderIdSize = (uint)fidLongTermId.Length; byte[] sourceFolderId = new byte[fidLongTermId.Length]; Array.Copy(fidLongTermId, 0, sourceFolderId, 0, fidLongTermId.Length); importMessageMoveRequest.SourceFolderId = sourceFolderId; // Get source message id byte[] midLongTermId = this.GetLongTermIdByte(serverId, sourceMID); importMessageMoveRequest.SourceMessageIdSize = (uint)midLongTermId.Length; byte[] sourceMessageId = new byte[midLongTermId.Length]; Array.Copy(midLongTermId, 0, sourceMessageId, 0, midLongTermId.Length); importMessageMoveRequest.SourceMessageId = sourceMessageId; // Get destination message id byte[] sub = new byte[4]; byte[] currentLocalId = this.localId; // Get local id. Array.Copy(currentLocalId, 2, sub, 0, currentLocalId.Length - 2); Array.Reverse(sub); int tempLocalId = BitConverter.ToInt32(sub, 0); tempLocalId += this.localIdOffSet; sub = BitConverter.GetBytes(tempLocalId); Array.Reverse(sub); Array.Copy(sub, 0, currentLocalId, 2, currentLocalId.Length - 2); this.localIdOffSet++; importMessageMoveRequest.DestinationMessageIdSize = (uint)(this.serverReplicaGuid.ToByteArray().Length + currentLocalId.Length); byte[] destinationMessageId = new byte[this.serverReplicaGuid.ToByteArray().Length + currentLocalId.Length]; Array.Copy(this.serverReplicaGuid.ToByteArray(), 0, destinationMessageId, 0, this.serverReplicaGuid.ToByteArray().Length); Array.Copy(currentLocalId, 0, destinationMessageId, this.serverReplicaGuid.ToByteArray().Length, currentLocalId.Length); LongTermId longtermid = new LongTermId { DatabaseGuid = this.serverReplicaGuid.ToByteArray(), GlobalCounter = currentLocalId }; // Get Mid from long termid. ulong destinationMID = this.GetIdFromLongTerm(serverId, longtermid); importMessageMoveRequest.DestinationMessageId = destinationMessageId; // Change number byte[] tempChangeNumber = this.GetChangeNumber(serverId, sourceMID, sourceFID, sourceFolderHandle); importMessageMoveRequest.ChangeNumberSize = (uint)tempChangeNumber.Length; // Generate a new change number. byte[] tempBytes = new byte[4]; Array.Copy(tempChangeNumber, tempChangeNumber.Length - 4, tempBytes, 0, 4); Array.Reverse(tempBytes); int num = BitConverter.ToInt32(tempBytes, 0); if (inewerClientChange == false) { // Make the message version older in client than that in server. num--; iolderversion = false; } else { // Make the message version newer in client than that in server. num++; iolderversion = true; } tempBytes = BitConverter.GetBytes(num); Array.Reverse(tempBytes); Array.Copy(tempBytes, 0, tempChangeNumber, tempChangeNumber.Length - 4, tempBytes.Length); importMessageMoveRequest.ChangeNumber = tempChangeNumber; // Set the PCL size value. importMessageMoveRequest.PredecessorChangeListSize = (uint)(tempChangeNumber.Length + 1); importMessageMoveRequest.PredecessorChangeList = new byte[tempChangeNumber.Length + 1]; importMessageMoveRequest.PredecessorChangeList[0] = (byte)tempChangeNumber.Length; Array.Copy(tempChangeNumber, 0, importMessageMoveRequest.PredecessorChangeList, 1, tempChangeNumber.Length); // Send request and get response. RopSynchronizationImportMessageMoveResponse synchronizationImportMessageMoveResponse = (RopSynchronizationImportMessageMoveResponse)this.Process(serverId, importMessageMoveRequest, synchronizationUploadContextHandle); result = (RopResult)synchronizationImportMessageMoveResponse.ReturnValue; if (result == RopResult.Success) { // Verify ROP SynchronizationImportMessageMove this.VerifyRopSynchronizationImportMessageMove(synchronizationImportMessageMoveResponse); int messageIdIndex = AdapterHelper.GetObjectIdIndex(); this.objectIdContainer.Add(messageIdIndex, destinationMID); icnpc = false; this.isNonImportMessageChangeOperation = true; } else if (result == RopResult.NewerClientChange) { // Verify ROP SynchronizationImportMessageMove this.VerifyRopSynchronizationImportMessageMove(synchronizationImportMessageMoveResponse); } this.isImportMessageMoveROP = true; return result; }