/// <summary>
        /// Gets the file corresponding to the given CasHash and checks
        /// to see if the file contents hash to the same CasHash value
        /// </summary>
        /// <param name="originalCasHash">CasHash value to check</param>
        /// <param name="errors">Where any cache errors found get stored</param>
        private async Task RehashContentsAsync(CasHash originalCasHash, ConcurrentDictionary <CacheError, int> errors)
        {
            if (originalCasHash.Equals(CasHash.NoItem))
            {
                // No need to rehash the NoItem cas hash
                return;
            }

            Possible <StreamWithLength, Failure> possibleStream = await m_readOnlySession.GetStreamAsync(originalCasHash);

            if (!possibleStream.Succeeded)
            {
                errors.TryAdd(new CacheError(CacheErrorType.CasHashError, "CasHash " + originalCasHash + " not found in CAS"), 0);
                return;
            }

            using (StreamWithLength stream = possibleStream.Result)
            {
                ContentHash contentHash = await ContentHashingUtilities.HashContentStreamAsync(stream);

                Hash    newHash    = new Hash(contentHash);
                CasHash newCasHash = new CasHash(newHash);
                if (!originalCasHash.Equals(newCasHash))
                {
                    errors.TryAdd(new CacheError(CacheErrorType.CasHashError, "The data of CasHash " + originalCasHash + " has been altered in the CAS"), 0);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets a file stream from the CAS either directly or by materlializing a file in the temp path and then opening it for read.
        /// </summary>
        /// <param name="hash">Hash for CAS entry</param>
        /// <param name="method">Method used to access CAS</param>
        /// <param name="session">Cache session</param>
        /// <returns>A stream pointing to the file contents, or a failure.</returns>
        private static async Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, CasAccessMethod method, ICacheReadOnlySession session)
        {
            switch (method)
            {
            case CasAccessMethod.Stream:
                return(await session.GetStreamAsync(hash));

            case CasAccessMethod.FileSystem:

                string filePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

                string placedFilePath = await session.ProduceFileAsync(hash, filePath, FileState.ReadOnly).SuccessAsync();

                XAssert.AreEqual(filePath, placedFilePath);

                FileStream fs = new FileStream(placedFilePath, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read);

                File.Delete(placedFilePath);

                return(fs.WithLength());

            default:
                throw new NotImplementedException();
            }
        }
 public async Task <Possible <Stream, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId)
 {
     using (var eventing = new GetStreamActivity(CompositingCache.EventSource, activityId, this))
     {
         eventing.Start(hash, urgencyHint);
         return(eventing.Returns(await m_casSession.GetStreamAsync(hash, urgencyHint, eventing.Id)));
     }
 }
        public Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId)
        {
            var callback = GetStreamAsyncCallback;

            if (callback != null)
            {
                return(callback(hash, urgencyHint, activityId, m_realSession));
            }
            else
            {
                return(m_realSession.GetStreamAsync(hash, urgencyHint, activityId));
            }
        }
Beispiel #5
0
        private async Task <long> PinAndGetStreamSize(ICacheReadOnlySession session, CasHash hash)
        {
            long result;

            await session.PinToCasAsync(hash, CancellationToken.None).SuccessAsync();

            using (var stream = await session.GetStreamAsync(hash).SuccessAsync())
            {
                result = stream.Length;
            }

            return(result);
        }
Beispiel #6
0
        internal static async Task <Tuple <CasHash, long> > GetContentSizeAsync(this ICacheReadOnlySession session, CasHash casHash)
        {
            var possibleString = await session.PinToCasAsync(casHash);

            if (!possibleString.Succeeded)
            {
                return(new Tuple <CasHash, long>(casHash, (long)ContentError.UnableToPin));
            }

            var possibleStream = await session.GetStreamAsync(casHash);

            if (!possibleStream.Succeeded)
            {
                return(new Tuple <CasHash, long>(casHash, (long)ContentError.UnableToStream));
            }

            long length = possibleStream.Result.Length;

            possibleStream.Result.Dispose();
            return(new Tuple <CasHash, long>(casHash, length));
        }
 public Task <Possible <StreamWithLength, Failure> > GetStreamAsync(CasHash hash, UrgencyHint urgencyHint, Guid activityId)
 {
     return(m_session.GetStreamAsync(hash, urgencyHint, activityId));
 }
Beispiel #8
0
        /// <summary>
        /// Takes a strong fingerprint and returns the deserialized contents of
        /// the input assertion list file that corresponds to it
        /// </summary>
        /// <param name="sfp">The strong fingerprint to get the input assertion
        /// list file contents for</param>
        /// <param name="cacheErrors">Any cache errors that are found will be
        /// added to this collection</param>
        /// <returns>Deserialized contents of the input assertion list file
        /// corresponding to the specified strong fingerprint</returns>
        private async Task <string> GetInputAssertionListFileContentsAsync(StrongFingerprint sfp, ConcurrentDictionary <CacheError, int> cacheErrors)
        {
            // Check for the NoItem
            if (sfp.CasElement.Equals(CasHash.NoItem))
            {
                return(string.Empty);
            }

            // Pin the input assertion list file
            Possible <string, Failure> possibleString = await m_readOnlySession.PinToCasAsync(sfp.CasElement).ConfigureAwait(false);

            if (!possibleString.Succeeded)
            {
                return(string.Empty);
            }

            // Get the stream for the input assertion list file
            Possible <Stream, Failure> possibleStream = await m_readOnlySession.GetStreamAsync(sfp.CasElement).ConfigureAwait(false);

            if (!possibleStream.Succeeded)
            {
                cacheErrors.TryAdd(
                    new CacheError(
                        CacheErrorType.CasHashError,
                        "The input assertion list for SFP " + sfp.ToString() + " was not found in CAS"), 0);
                return(string.Empty);
            }

            // Read the stream contents while hashing
            return(await Task.Run(() =>
            {
                using (var hasher = ContentHashingUtilities.HashInfo.CreateContentHasher())
                {
                    using (var hashingStream = hasher.CreateReadHashingStream(possibleStream.Result))
                    {
                        using (var reader = new BuildXLReader(false, hashingStream, false))
                        {
                            var maybePathSet = ObservedPathSet.TryDeserialize(s_pathTable, reader);

                            // Check if deserialization was successful
                            if (!maybePathSet.Succeeded)
                            {
                                // Deserialization failed
                                cacheErrors.TryAdd(
                                    new CacheError(
                                        CacheErrorType.CasHashError,
                                        "The input assertion list for SFP " + sfp.ToString() + " could not be deserialized"), 0);
                                return string.Empty;
                            }

                            CasHash newCasHash = new CasHash(hashingStream.GetContentHash());

                            // Check if the hashes match
                            if (!sfp.CasElement.Equals(newCasHash))
                            {
                                cacheErrors.TryAdd(
                                    new CacheError(
                                        CacheErrorType.CasHashError,
                                        "The input assertion list for SFP " + sfp.ToString() + " has been altered in the CAS"), 0);
                                return string.Empty;
                            }

                            // Deserialization was successful and file was unaltered
                            StringBuilder fileContents = new StringBuilder();
                            foreach (ObservedPathEntry entry in maybePathSet.Result.Paths)
                            {
                                fileContents.Append(entry.Path.ToString(s_pathTable)).Append(Environment.NewLine);
                            }

                            return fileContents.ToString();
                        }
                    }
                }
            }).ConfigureAwait(false));
        }