internal virtual bool TryMoveFile(string sourceFilePath, string targetFilePath) { if (sourceFilePath.IsNullOrEmpty()) { throw new ArgumentNullException("sourceFilePath"); } if (targetFilePath.IsNullOrEmpty()) { throw new ArgumentNullException("targetFilePath"); } var transaction = Transaction.Current; if (transaction == null) { return(TryIoOperation( () => File.Move(sourceFilePath, targetFilePath), string.Format("Failed to move file from '{0}' to '{1}'.", sourceFilePath, targetFilePath))); } // ReSharper disable once SuspiciousTypeConversion.Global var kernelTransaction = (IKernelTransaction)TransactionInterop.GetDtcTransaction(transaction); return(TryIoOperation( () => FileTransacted.Move(sourceFilePath, targetFilePath, kernelTransaction), string.Format("Failed to transactionally move file from '{0}' to '{1}'.", sourceFilePath, targetFilePath))); }
/// <summary> /// Create a <see cref="Stream"/> to an entry in the claim store that piggies back a kernel transaction if one can /// be factored. /// </summary> /// <param name="url"> /// The claim store entry. /// </param> /// <param name="trackingModes"> /// </param> /// <param name="transactionFactory"> /// The <see cref="IKernelTransaction"/> factory. /// </param> /// <returns> /// The <see cref="Stream"/> to the claim store entry. /// </returns> private Stream CreateCapturingStream(string url, ActivityTrackingModes trackingModes, Func <IKernelTransaction> transactionFactory) { // RequiresCheckInAndOut entails payloads are first saved locally and moved by ClaimStore.Agent into claim // store where there will be a subfolder for each date that some payload has been saved/tracked to disk. To // ease the job of the ClaimStore.Agent the subfolder is not created locally (but the current date is however // kept in the name). When not RequiresCheckInAndOut, the payloads are tracked/saved to disk at the exact same // place that it will be redeemed from afterwards, that is in a subfolder corresponding to the current date (of // course, one needs to ensure the folders get created). string filePath; if (RequiresCheckInAndOut) { // .trk extension is used to denote simple message body's payload tracking scenarios, i.e. where the // message's payload is large enough that it would not fit in the BAM tracking database. Message body's // payload are therefore tracked to the local disk are then brought asynchronously to the central claim // store by the ClaimStore.Agent. // .chk extension is used to denote full-fledged claim check scenarios, i.e. where the actual message's // payload is claimed to disk (as with regular tracking) but also replaced by a token that needs to be // checked in and out. Message body's payload are claimed to the local disk and then brought asynchronously // to the central claim store by the ClaimStore.Agent. Because claims are brought asynchronously to the // central claim store, one has therefore to ensure a claim is available in the central claim store before // it could be redeemed. // The .chk and .trk extensions are there to allow the ClaimStore.Agent to distinguish these scenarios so // that it can, (1) bring claimed or tracked payloads to the central claim store and (2) make claims // available for redeem as soon as they have been brought to the central store. var extension = trackingModes.RequiresBodyClaimChecking() ? ".chk" : ".trk"; filePath = Path.Combine(CheckInDirectory, url.Replace("\\", "") + extension); } else { filePath = Path.Combine(CheckInDirectory, url); // ReSharper disable once AssignNullToNotNullAttribute Directory.CreateDirectory(Path.GetDirectoryName(filePath)); } return(FileTransacted.Create(filePath, 8192, transactionFactory.IfNotNull(ktf => ktf()))); }