Exemple #1
0
        /// <summary>
        /// Read a list of <see cref="Thing"/>s in the associated <see cref="IDal"/>
        /// </summary>
        /// <param name="things">The <see cref="IEnumerable{Thing}"/> that contains the <see cref="Thing"/> to read</param>
        /// <param name="queryAttributes">The <see cref="IQueryAttributes"/> to be used to read data</param>
        /// <returns>
        /// an await-able <see cref="Task"/>
        /// </returns>
        public async Task Read(IEnumerable <Thing> things, IQueryAttributes queryAttributes)
        {
            if (this.ActivePerson == null)
            {
                throw new InvalidOperationException("The data cannot be read when the ActivePerson is null; The Open method must be called prior to any of the Read methods");
            }

            var thingList = things.ToList();

            if (!thingList.Any())
            {
                throw new ArgumentException("The requested list of things is null or empty.");
            }

            logger.Info("Session.Read {0} things", thingList.Count());

            var foundThings = new List <CDP4Common.DTO.Thing>();

            // Create the token source
            var cancellationTokenSource = new CancellationTokenSource();
            var cancellationTokenKey    = Guid.NewGuid();

            this.cancellationTokenSourceDictionary.TryAdd(cancellationTokenKey, cancellationTokenSource);

            try
            {
                // Max 10 async calls at a time, otherwise we could create a sort of a DDOS attack to the DAL/webservice
                var loopCount = 10;

                while (thingList.Any())
                {
                    var tasks = new List <Task <IEnumerable <CDP4Common.DTO.Thing> > >();

                    foreach (var thing in thingList.Take(loopCount))
                    {
                        tasks.Add(this.Dal.Read(thing.ToDto(), cancellationTokenSource.Token, queryAttributes));
                    }

                    var newThings = (await Task.WhenAll(tasks.ToArray())).SelectMany(x => x).ToList();

                    foundThings.AddRange(newThings);

                    thingList = thingList.Skip(loopCount).ToList();
                }
            }
            catch (OperationCanceledException)
            {
                logger.Info("Session.Read cancelled");
                return;
            }
            finally
            {
                this.cancellationTokenSourceDictionary.TryRemove(cancellationTokenKey, out cancellationTokenSource);
            }

            await this.AfterReadOrWriteOrUpdate(foundThings);
        }
Exemple #2
0
        /// <summary>
        /// Read a <see cref="Thing"/> in the associated <see cref="IDal"/>
        /// </summary>
        /// <param name="thing">The <see cref="Thing"/> to read</param>
        /// <param name="queryAttributes">The <see cref="IQueryAttributes"/> to be used to read data</param>
        /// <returns>
        /// an await-able <see cref="Task"/>
        /// </returns>
        public async Task Read(Thing thing, IQueryAttributes queryAttributes)
        {
            if (this.ActivePerson == null)
            {
                throw new InvalidOperationException($"The {thing.ClassKind} cannot be read when the ActivePerson is null; The Open method must be called prior to any of the Read methods");
            }

            logger.Info("Session.Read {0} {1}", thing.ClassKind, thing.Iid);
            var dto = thing.ToDto();

            // Create the token source
            var cancellationTokenSource = new CancellationTokenSource();
            var cancellationTokenKey    = Guid.NewGuid();

            this.cancellationTokenSourceDictionary.TryAdd(cancellationTokenKey, cancellationTokenSource);

            IEnumerable <CDP4Common.DTO.Thing> dtoThings;

            try
            {
                dtoThings = await this.Dal.Read(dto, cancellationTokenSource.Token, queryAttributes);
            }
            catch (OperationCanceledException)
            {
                logger.Info("Session.Read {0} {1} cancelled", thing.ClassKind, thing.Iid);
                return;
            }
            finally
            {
                this.cancellationTokenSourceDictionary.TryRemove(cancellationTokenKey, out cancellationTokenSource);
            }

            // proceed if no problem
            var enumerable = dtoThings as IList <CDP4Common.DTO.Thing> ?? dtoThings.ToList();

            await this.AfterReadOrWriteOrUpdate(enumerable);
        }
Exemple #3
0
 public override Task <IEnumerable <Thing> > Read(Iteration iteration, CancellationToken cancellationToken, IQueryAttributes attributes = null)
 {
     throw new NotImplementedException();
 }
Exemple #4
0
 public override Task <IEnumerable <Thing> > Read <T>(T thing, CancellationToken token, IQueryAttributes attributes = null)
 {
     throw new System.NotImplementedException();
 }
        /// <summary>
        /// Reads the data related to the provided <see cref="Thing"/> from the data-source
        /// </summary>
        /// <typeparam name="T">
        /// an type of <see cref="Thing"/>
        /// </typeparam>
        /// <param name="thing">
        /// An instance of <see cref="Thing"/> that needs to be read from the data-source
        /// </param>
        /// <param name="cancellationToken">
        /// The <see cref="CancellationToken"/>
        /// </param>
        /// <param name="attributes">
        /// An instance of <see cref="IQueryAttributes"/> to be passed along with the request
        /// </param>
        /// <returns>
        /// a list of <see cref="Thing"/> that are contained by the provided <see cref="Thing"/> including the <see cref="Thing"/> itself
        /// </returns>
        public override async Task <IEnumerable <Thing> > Read <T>(T thing, CancellationToken cancellationToken, IQueryAttributes attributes = null)
        {
            if (this.Credentials == null || this.Credentials.Uri == null)
            {
                throw new InvalidOperationException("The CDP4 DAL is not open.");
            }

            if (thing == null)
            {
                throw new ArgumentNullException(nameof(thing), $"The {nameof(thing)} may not be null");
            }

            var watch = Stopwatch.StartNew();

            if (attributes == null)
            {
                var includeReferenData = thing is ReferenceDataLibrary;

                attributes = this.GetIUriQueryAttribute(includeReferenData);
            }

            var thingRoute = this.CleanUriFinalSlash(thing.Route);

            var resourcePath = $"{thingRoute}{attributes?.ToString()}";

            var readToken  = CDP4Common.Helpers.TokenGenerator.GenerateRandomToken();
            var uriBuilder = this.GetUriBuilder(this.Credentials.Uri, ref resourcePath);

            Logger.Debug("Resource Path {0}: {1}", readToken, resourcePath);
            Logger.Debug("CDP4Services GET {0}: {1}", readToken, uriBuilder);

            var requestsw = Stopwatch.StartNew();

            var requestMessage = new HttpRequestMessage(HttpMethod.Get, resourcePath);

            requestMessage.Headers.Add(Headers.CDPToken, readToken);

            using (var httpResponseMessage = await this.httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
            {
                Logger.Info("CDP4 Services responded in {0} [ms] to GET {1}", requestsw.ElapsedMilliseconds, readToken);
                requestsw.Stop();

                if (httpResponseMessage.StatusCode != HttpStatusCode.OK)
                {
                    var msg = $"The data-source replied with code {httpResponseMessage.StatusCode}: {httpResponseMessage.ReasonPhrase}";
                    Logger.Error(msg);
                    throw new DalReadException(msg);
                }

                this.ProcessHeaders(httpResponseMessage);

                using (var resultStream = await httpResponseMessage.Content.ReadAsStreamAsync())
                {
                    var returned = this.Serializer.Deserialize(resultStream);

                    if (this.TryExtractIterationIdfromUri(httpResponseMessage.RequestMessage.RequestUri, out var iterationId))
                    {
                        this.SetIterationContainer(returned, iterationId);
                    }

                    watch.Stop();
                    Logger.Info("JSON Deserializer completed in {0} [ms]", watch.ElapsedMilliseconds);

                    return(returned);
                }
            }
        }
        /// <summary>
        /// Reads the data related to the provided <see cref="CDP4Common.EngineeringModelData.Iteration"/> from the data-source
        /// </summary>
        /// <param name="iteration">
        /// An instance of <see cref="CDP4Common.EngineeringModelData.Iteration"/> that needs to be read from the data-source
        /// </param>
        /// <param name="cancellationToken">
        /// The <see cref="CancellationToken"/>
        /// </param>
        /// <param name="attributes">
        /// An instance of <see cref="IQueryAttributes"/> to be used with the request
        /// </param>
        /// <returns>
        /// A list of <see cref="Thing"/> that are contained by the provided <see cref="CDP4Common.EngineeringModelData.EngineeringModel"/> including the Reference-Data.
        /// All the <see cref="Thing"/>s that have been updated since the last read will be returned.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown when the <see cref="Session"/> property has not been set
        /// </exception>
        public override async Task <IEnumerable <Thing> > Read(CDP4Common.DTO.Iteration iteration, CancellationToken cancellationToken, IQueryAttributes attributes = null)
        {
            if (this.Session == null)
            {
                throw new InvalidOperationException("The Session may not be null and must be set prior to reading an Iteration");
            }

            // Get the RequiredRdl to load
            var siteDirectory  = this.Session.Assembler.RetrieveSiteDirectory();
            var iterationSetup = siteDirectory.Model.SelectMany(mod => mod.IterationSetup).SingleOrDefault(it => it.IterationIid == iteration.Iid);

            if (iterationSetup == null)
            {
                throw new InvalidOperationException("The Iteration to open does not have any associated IterationSetup.");
            }

            var modelSetup = (EngineeringModelSetup)iterationSetup.Container;
            var modelReferenceDataLibrary = modelSetup.RequiredRdl.SingleOrDefault();

            if (modelReferenceDataLibrary == null)
            {
                throw new InvalidOperationException("The model to open does not have a Required Reference-Data-Library.");
            }

            var modelReferenceDataLibraryDto = modelReferenceDataLibrary.ToDto();

            var result        = new List <Thing>();
            var referenceData = await this.Read(modelReferenceDataLibraryDto, cancellationToken);

            result.AddRange(referenceData);
            var engineeringModelData = await this.Read((Thing)iteration, cancellationToken);

            result.AddRange(engineeringModelData);
            return(result);
        }
 /// <summary>
 /// Reads the data related to the provided <see cref="Thing"/> from the data-source
 /// </summary>
 /// <typeparam name="T">
 /// an type of <see cref="Thing"/>
 /// </typeparam>
 /// <param name="thing">
 /// An instance of <see cref="Thing"/> that needs to be read from the data-source
 /// </param>
 /// <param name="cancellationToken">
 /// The <see cref="CancellationToken"/>
 /// </param>
 /// <param name="attributes">
 /// An instance of <see cref="IQueryAttributes"/> to be used with the request
 /// </param>
 /// <returns>
 /// A list of <see cref="Thing"/> that are contained by the provided <see cref="Thing"/> including the <see cref="Thing"/>.
 /// In case the
 /// <param name="thing">
 /// </param>
 /// is a top container then all the <see cref="Thing"/>s that have been updated since the
 /// last read will be returned.
 /// </returns>
 public Task <IEnumerable <Thing> > Read <T>(T thing, CancellationToken cancellationToken, IQueryAttributes attributes = null) where T : Thing
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Reads the data related to the provided <see cref="CDP4Common.EngineeringModelData.Iteration"/> from the data-source
 /// </summary>
 /// <param name="iteration">
 /// An instance of <see cref="CDP4Common.EngineeringModelData.Iteration"/> that needs to be read from the data-source
 /// </param>
 /// <param name="cancellationToken">
 /// The <see cref="CancellationToken"/>
 /// </param>
 /// <param name="attributes">
 /// An instance of <see cref="IQueryAttributes"/> to be used with the request
 /// </param>
 /// <returns>
 /// A list of <see cref="Thing"/> that are contained by the provided <see cref="CDP4Common.EngineeringModelData.EngineeringModel"/> including the Reference-Data.
 /// All the <see cref="Thing"/>s that have been updated since the last read will be returned.
 /// </returns>
 public override async Task <IEnumerable <Thing> > Read(CDP4Common.DTO.Iteration iteration, CancellationToken cancellationToken, IQueryAttributes attributes = null)
 {
     return(await this.Read((Thing)iteration, cancellationToken, attributes));
 }
        /// <summary>
        /// Reads the data related to the provided <see cref="CDP4Common.DTO.Thing"/> from the data-source
        /// </summary>
        /// <typeparam name="T">
        /// an type of <see cref="CDP4Common.DTO.Thing"/>
        /// </typeparam>
        /// <param name="thing">
        /// An instance of <see cref="CDP4Common.DTO.Thing"/> that needs to be read from the data-source
        /// </param>
        /// <param name="cancellationToken">
        /// The cancellation Token.
        /// </param>
        /// <param name="attributes">
        /// An instance of <see cref="IQueryAttributes"/> to be passed along with the uri
        /// </param>
        /// <returns>
        /// a list of <see cref="CDP4Common.DTO.Thing"/> that are contained by the provided <see cref="CDP4Common.DTO.Thing"/> including the <see cref="CDP4Common.DTO.Thing"/> itself
        /// </returns>
        /// <exception cref="NotSupportedException">
        /// Throws a <see cref="NotSupportedException"/> if the supplied T thing is not an <see cref="CDP4Common.DTO.Iteration"/>.
        /// </exception>
        public override async Task <IEnumerable <Thing> > Read <T>(T thing, CancellationToken cancellationToken, IQueryAttributes attributes = null)
        {
            // only read Iterations,  domains or site reference data libraries in a file Dal
            if (!(thing is CDP4Common.DTO.Iteration) && !(thing is CDP4Common.DTO.SiteReferenceDataLibrary) && !(thing is CDP4Common.DTO.DomainOfExpertise))
            {
                throw new NotSupportedException("The JSONFileDal only supports Read on Iteration, SiteReferenceDataLibrary and DomainOfExpertise instances.");
            }

            if (this.Credentials.Uri == null)
            {
                throw new ArgumentNullException(nameof(this.Credentials.Uri), $"The Credentials URI may not be null");
            }

            // make sure that the uri is of the correct format
            UriExtensions.AssertUriIsFileSchema(this.Credentials.Uri);

            var filePath = this.Credentials.Uri.LocalPath;

            if (!System.IO.File.Exists(filePath))
            {
                throw new FileNotFoundException($"The specified filepath does not exist or you do not have access to it: {filePath}");
            }

            try
            {
                // re-read the to extract the reference data libraries that have not yet been fully dereferenced
                // and that are part of the required RDL's
                var siteDirectoryData = this.ReadSiteDirectoryJson(filePath, this.Credentials).ToList();

                // read file, SiteDirectory first.
                using (var zip = ZipFile.Read(filePath))
                {
                    // get all relevant info from the selected iteration
                    var siteDir = this.Session.RetrieveSiteDirectory();

                    var returned = new List <Thing>();

                    switch (thing.ClassKind)
                    {
                    case ClassKind.Iteration:
                        returned = this.RetrieveIterationThings(thing as CDP4Common.DTO.Iteration, siteDirectoryData, zip, siteDir);
                        break;

                    case ClassKind.SiteReferenceDataLibrary:
                        returned = this.RetrieveSRDLThings(thing as CDP4Common.DTO.SiteReferenceDataLibrary, siteDirectoryData, zip, siteDir);
                        break;

                    case ClassKind.DomainOfExpertise:
                        returned = this.RetrieveDomainOfExpertiseThings(thing as CDP4Common.DTO.DomainOfExpertise, siteDirectoryData, siteDir);
                        break;
                    }

                    return(returned);
                }
            }
            catch (Exception ex)
            {
                var msg = $"Failed to load file. Error: {ex.Message}";
                Logger.Error(msg);

                if (this.Credentials != null)
                {
                    this.Close();
                }

                throw new FileLoadException(msg);
            }
        }
 /// <summary>
 /// Reads the data related to the provided <see cref="CDP4Common.DTO.Iteration"/> from the data-source
 /// </summary>
 /// <param name="iteration">
 /// An instance of <see cref="CDP4Common.DTO.Iteration"/> that needs to be read from the data-source
 /// </param>
 /// <param name="cancellationToken">
 /// The <see cref="CancellationToken"/>
 /// </param>
 /// <param name="attributes">
 /// An instance of <see cref="IQueryAttributes"/> to be used with the request
 /// </param>
 /// <returns>
 /// A list of <see cref="Thing"/> that are contained by the provided <see cref="CDP4Common.DTO.EngineeringModel"/> including the Reference-Data.
 /// All the <see cref="Thing"/>s that have been updated since the last read will be returned.
 /// </returns>
 public abstract Task <IEnumerable <Thing> > Read(Iteration iteration, CancellationToken cancellationToken, IQueryAttributes attributes = null);
 /// <summary>
 /// Reads the data related to the provided <see cref="Thing"/> from the data-source
 /// </summary>
 /// <typeparam name="T">
 /// an type of <see cref="Thing"/>
 /// </typeparam>
 /// <param name="thing">
 /// An instance of <see cref="Thing"/> that needs to be read from the data-source
 /// </param>
 /// <param name="token">
 /// The <see cref="CancellationToken"/>
 /// </param>
 /// <param name="attributes">
 /// An instance of <see cref="IQueryAttributes"/> to be passed along with the request
 /// </param>
 /// <returns>
 /// a list of <see cref="Thing"/> that are contained by the provided <see cref="Thing"/> including the <see cref="Thing"/> itself
 /// </returns>
 public abstract Task <IEnumerable <Thing> > Read <T>(T thing, CancellationToken token, IQueryAttributes attributes = null) where T : Thing;