public async Task VerifyThatReadReturnsCorrectDTO() { this.dal = new WspDal(); var returned = (await this.dal.Open(this.credentials, this.cancelationTokenSource.Token)).ToList(); Assert.NotNull(returned); Assert.IsNotEmpty(returned); var sd = returned.First(); var attributes = new QueryAttributes(); var readResult = await dal.Read(sd, this.cancelationTokenSource.Token, attributes); // General assertions for any kind of Thing we read Assert.NotNull(readResult); Assert.IsTrue(readResult.Count() == 1); var sd1 = readResult.Single(); Assert.IsTrue(sd.ClassKind == sd1.ClassKind); Assert.IsTrue(sd.Iid == sd1.Iid); Assert.IsTrue(sd.Route == sd1.Route); // Specific assertions for Sitedirectory ClassKind var castedSd = sd as CDP4Common.DTO.SiteDirectory; var castedSd1 = sd as CDP4Common.DTO.SiteDirectory; Assert.NotNull(castedSd); Assert.NotNull(castedSd1); Assert.IsTrue(castedSd.Name == castedSd1.Name); Assert.IsTrue(castedSd.Domain.Count == castedSd1.Domain.Count); Assert.IsTrue(castedSd.SiteReferenceDataLibrary == castedSd1.SiteReferenceDataLibrary); Assert.IsTrue(castedSd.Model == castedSd1.Model); }
internal MongoQueryObject Build(Expression expression) { _queryObject = new MongoQueryObject(); _queryAttributes = new QueryAttributesGatherer().Gather(expression); _queryObject.IsCount = _queryAttributes.IsCount; _queryObject.IsMapReduce = _queryAttributes.IsMapReduce; Visit(expression); return(_queryObject); }
public async Task Verify_that_multiple_read_requests_can_be_made_in_parallel() { var uri = new Uri("https://cdp4services-test.cdp4.org"); var credentials = new Credentials("admin", "pass", uri); var assembler = new Assembler(this.uri); var dal = new CdpServicesDal(); var session = new Session(dal, credentials); var result = await dal.Open(credentials, new CancellationToken()); var siteDirectory = result.OfType <CDP4Common.DTO.SiteDirectory>().Single(); var queryAttributes = new QueryAttributes { Extent = ExtentQueryAttribute.deep }; for (int i = 0; i < 9; i++) { dal.Read(siteDirectory, new CancellationToken(), queryAttributes); } var readresult = await dal.Read(siteDirectory, new CancellationToken()); }
/// <summary> /// Opens a connection to a data source <see cref="Uri"/> speci1fied by the provided <see cref="Credentials"/> /// </summary> /// <param name="credentials"> /// The <see cref="Dal.Credentials"/> that are used to connect to the data source such as username, password and <see cref="Uri"/> /// </param> /// <param name="cancellationToken"> /// The cancellation Token. /// </param> /// <returns> /// The <see cref="IEnumerable{T}"/> that the services return when connecting to the <see cref="CDP4Common.SiteDirectoryData.SiteDirectory"/>. /// </returns> public override async Task <IEnumerable <Thing> > Open(Credentials credentials, CancellationToken cancellationToken) { if (credentials == null) { throw new ArgumentNullException(nameof(credentials), $"The {nameof(credentials)} may not be null"); } if (credentials.Uri == null) { throw new ArgumentNullException(nameof(credentials.Uri), $"The Credentials URI may not be null"); } UriExtensions.AssertUriIsHttpOrHttpsSchema(credentials.Uri); var queryAttributes = new QueryAttributes { Extent = ExtentQueryAttribute.deep, IncludeReferenceData = false }; var resourcePath = $"SiteDirectory{queryAttributes}"; var openToken = CDP4Common.Helpers.TokenGenerator.GenerateRandomToken(); this.httpClient = this.CreateHttpClient(credentials); var watch = Stopwatch.StartNew(); var uriBuilder = this.GetUriBuilder(credentials.Uri, ref resourcePath); Logger.Debug("Resource Path {0}: {1}", openToken, resourcePath); Logger.Debug("CDP4Services Open {0}: {1}", openToken, uriBuilder); var requestsw = Stopwatch.StartNew(); var requestMessage = new HttpRequestMessage(HttpMethod.Get, resourcePath); requestMessage.Headers.Add(Headers.CDPToken, openToken); using (var httpResponseMessage = await this.httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken: cancellationToken)) { Logger.Info("CDP4 Services responded in {0} [ms] to Open {1}", requestsw.ElapsedMilliseconds, openToken); 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); } watch.Stop(); Logger.Info("CDP4Services Open {0}: {1} completed in {2} [ms]", openToken, uriBuilder, watch.ElapsedMilliseconds); this.ProcessHeaders(httpResponseMessage); watch = Stopwatch.StartNew(); using (var resultStream = await httpResponseMessage.Content.ReadAsStreamAsync()) { var returned = this.Serializer.Deserialize(resultStream); watch.Stop(); Logger.Info("JSON Deserializer completed in {0} [ms]", watch.ElapsedMilliseconds); var returnedPerson = returned.OfType <CDP4Common.DTO.Person>().SingleOrDefault(x => x.ShortName == credentials.UserName); if (returnedPerson == null) { throw new InvalidOperationException("User not found."); } this.Credentials = credentials; return(returned); } } }
/// <summary> /// Write all the <see cref="Operation"/>s from an <see cref="OperationContainer"/> asynchronously. /// </summary> /// <param name="operationContainer"> /// The provided <see cref="OperationContainer"/> to write /// </param> /// <returns> /// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation. /// </returns> public override async Task <IEnumerable <Thing> > Write(OperationContainer operationContainer, IEnumerable <string> files = null) { if (this.Credentials == null || this.Credentials.Uri == null) { throw new InvalidOperationException("The CDP4 DAL is not open."); } if (operationContainer == null) { throw new ArgumentNullException(nameof(operationContainer), $"The {nameof(operationContainer)} may not be null"); } if (operationContainer.Operations.Count() == 0) { Logger.Debug("The operationContainer is empty, no round trip to the datasource is made"); return(Enumerable.Empty <Thing>()); } var watch = Stopwatch.StartNew(); var result = new List <Thing>(); if (files != null && files.Any()) { this.OperationContainerFileVerification(operationContainer, files); } var attribute = new QueryAttributes { RevisionNumber = operationContainer.TopContainerRevisionNumber }; var postToken = operationContainer.Token; var resourcePath = $"{operationContainer.Context}{attribute}"; var uriBuilder = this.GetUriBuilder(this.Credentials.Uri, ref resourcePath); Logger.Debug("Resource Path {0}: {1}", postToken, resourcePath); Logger.Debug("CDP4 Services POST: {0} - {1}", postToken, uriBuilder); var requestContent = this.CreateHttpContent(postToken, operationContainer, files); var requestsw = Stopwatch.StartNew(); using (var httpResponseMessage = await this.httpClient.PostAsync(resourcePath, requestContent)) { Logger.Info("CDP4 Services responded in {0} [ms] to POST {1}", requestsw.ElapsedMilliseconds, postToken); requestsw.Stop(); if (httpResponseMessage.StatusCode != HttpStatusCode.OK) { var errorResponse = await httpResponseMessage.Content.ReadAsStringAsync(); var msg = $"The CDP4 Services replied with code {httpResponseMessage.StatusCode}: {httpResponseMessage.ReasonPhrase}: {errorResponse}"; Logger.Error(msg); throw new DalWriteException(msg); } this.ProcessHeaders(httpResponseMessage); using (var resultStream = await httpResponseMessage.Content.ReadAsStreamAsync()) { result.AddRange(this.Serializer.Deserialize(resultStream)); Guid iterationId; if (this.TryExtractIterationIdfromUri(httpResponseMessage.RequestMessage.RequestUri, out iterationId)) { this.SetIterationContainer(result, iterationId); } } } watch.Stop(); Logger.Info("Write Operation completed in {0} [ms]", watch.ElapsedMilliseconds); return(result); }
/// <summary> /// Write all the <see cref="Operation"/>s from an <see cref="OperationContainer"/> asynchronously. /// </summary> /// <param name="operationContainer"> /// The provided <see cref="OperationContainer"/> to write /// </param> /// <param name="files"> /// The path to the files that need to be uploaded. If <paramref name="files"/> is null, then no files are to be uploaded /// </param> /// <returns> /// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation. /// </returns> public override async Task <IEnumerable <Thing> > Write(OperationContainer operationContainer, IEnumerable <string> files = null) { if (this.Credentials == null || this.Credentials.Uri == null) { throw new InvalidOperationException("The CDP4 DAL is not open."); } if (operationContainer == null) { throw new ArgumentNullException(nameof(operationContainer), $"The {nameof(operationContainer)} may not be null"); } if (operationContainer.Operations.Count() == 0) { Logger.Debug("The operationContainer is empty, no round trip to the datasource is made"); return(Enumerable.Empty <Thing>()); } var watch = Stopwatch.StartNew(); var hasCopyValuesOperations = operationContainer.Operations.Any(op => OperationKindExtensions.IsCopyKeepOriginalValuesOperation(op.OperationKind)); var modifier = new OperationModifier(this.Session); var copyHandler = new CopyOperationHandler(this.Session); copyHandler.ModifiedCopyOperation(operationContainer); modifier.ModifyOperationContainer(operationContainer); var invalidOperationKind = operationContainer.Operations.Any(operation => operation.OperationKind == OperationKind.Move || OperationKindExtensions.IsCopyOperation(operation.OperationKind)); if (invalidOperationKind) { throw new InvalidOperationKindException("The WSP DAL does not support Copy or Move operations"); } var result = new List <Thing>(); if (files != null && files.Any()) { this.OperationContainerFileVerification(operationContainer, files); } var attribute = new QueryAttributes { RevisionNumber = operationContainer.TopContainerRevisionNumber }; var postToken = operationContainer.Token; var resourcePath = $"{operationContainer.Context}{attribute}"; var uriBuilder = this.GetUriBuilder(this.Credentials.Uri, ref resourcePath); Logger.Debug("Resource Path {0}: {1}", postToken, resourcePath); Logger.Debug("WSP Dal POST: {0} - {1}", postToken, uriBuilder); var requestContent = this.CreateHttpContent(postToken, operationContainer, files); var requestsw = Stopwatch.StartNew(); using (var httpResponseMessage = await this.httpClient.PostAsync(resourcePath, requestContent)) { Logger.Info("The ECSS-E-TM-10-25A Annex C Services responded in {0} [ms] to POST {1}", requestsw.ElapsedMilliseconds, postToken); requestsw.Stop(); if (httpResponseMessage.StatusCode != HttpStatusCode.OK) { var errorResponse = await httpResponseMessage.Content.ReadAsStringAsync(); var msg = $"The ECSS-E-TM-10-25A Annex C Services replied with code {httpResponseMessage.StatusCode}: {httpResponseMessage.ReasonPhrase}: {errorResponse}"; Logger.Error(msg); throw new DalWriteException(msg); } using (var resultStream = await httpResponseMessage.Content.ReadAsStreamAsync()) { result.AddRange(this.Serializer.Deserialize(resultStream)); Guid iterationId; if (this.TryExtractIterationIdfromUri(httpResponseMessage.RequestMessage.RequestUri, out iterationId)) { this.SetIterationContainer(result, iterationId); } } } // Update value-sets if (hasCopyValuesOperations) { var valueSetCopyHandler = new ValueSetOperationCreator(this.Session); var valueSetOperationContainer = valueSetCopyHandler.CreateValueSetsUpdateOperations(operationContainer.Context, result, copyHandler.CopyThingMap); var valueSetResult = await this.Write(valueSetOperationContainer); // merge dtos foreach (var valueSetDto in valueSetResult) { var index = result.FindIndex(x => x.Iid == valueSetDto.Iid); if (index >= 0) { result[index] = valueSetDto; } } } watch.Stop(); Logger.Info("Write Operation completed in {0} [ms]", watch.ElapsedMilliseconds); return(result); }
public void Setup() { this.attributes = new QueryAttributes();; }