private void VerifyChangeOnServer(ChangeData change, IAsyncContinuation continuation) { //// For now use different data service context to re-query and verify entities and links. //// In the future consider using an 'Oracle' component to re-query the changes if/when it comes online. using (IWrapperScope scope = new NullWrapperScope()) { WrappedDataServiceContext otherContext = this.DataServiceContextCreator.CreateContext(scope, this.currentContextData.ContextType, this.currentContextData.BaseUri); otherContext.ResolveName = this.currentContextData.ResolveName; otherContext.ResolveType = this.currentContextData.ResolveType; otherContext.IgnoreResourceNotFoundException = true; var uri = change.GetUriForRequery(); otherContext.Execute <WrappedObject>( continuation, this.Asynchronous, change.ClrTypeForRequery, uri, results => { var result = results.ToList(); VerifyChangeOnServer(change, otherContext, result); continuation.Continue(); }); } }
/// <summary> /// Creates a default wrapped data service context. /// </summary> /// <param name="scope">DataServiceContext TrackingScope</param> /// <param name="dataServiceContextType">The type of the DataServiceContext instance to be created</param> /// <param name="serviceBaseUri">service BaseUri</param> /// <returns>Wrapped DataServiceContext</returns> public virtual WrappedDataServiceContext CreateContext(IWrapperScope scope, Type dataServiceContextType, Uri serviceBaseUri) { WrappedDataServiceContext ctx = this.CreateContextWithoutSendingRequest(scope, dataServiceContextType, serviceBaseUri); this.RegisterSendingRequestEvent(ctx); return(ctx); }
/// <summary> /// Creates a default wrapped data service context without registering SendingRequest(2) event. /// </summary> /// <param name="scope">DataServiceContext TrackingScope</param> /// <param name="dataServiceContextType">The type of the DataServiceContext instance to be created</param> /// <param name="serviceBaseUri">service BaseUri</param> /// <returns>Wrapped DataServiceContext</returns> public WrappedDataServiceContext CreateContextWithoutSendingRequest(IWrapperScope scope, Type dataServiceContextType, Uri serviceBaseUri) { ExceptionUtilities.CheckAllRequiredDependencies(this); ExceptionUtilities.CheckArgumentNotNull(scope, "scope"); ExceptionUtilities.CheckArgumentNotNull(dataServiceContextType, "dataServiceContextType"); ExceptionUtilities.Assert(typeof(DataServiceContext).IsAssignableFrom(dataServiceContextType), "Given type did not derive from DataServiceContext"); WrappedDataServiceContext ctx = scope.CreateDataServiceContext(dataServiceContextType, serviceBaseUri, this.MaxProtocolVersion); DataServiceContext context = ctx.Product as DataServiceContext; this.SetCredentials(context); this.authenticationHeaders = this.AuthenticationProvider.GetAuthenticationHeaders(); this.SetAcceptAndContentTypeHeaders(context); //ctx.UndeclaredPropertyBehavior = this.UndeclaredPropertyBehavior; this.FormatApplier.Apply(context); if (this.FormatApplier.IsUsingContentType(MimeTypes.ApplicationJsonLight)) { // Setup the resolver. context.ResolveType = (name) => dataServiceContextType.Assembly.GetType(name); context.ResolveName = (type) => type.Namespace + "." + type.Name; } #if !WINDOWS_PHONE if (this.EntitySetResolver != null) { ctx.ResolveEntitySet = this.EntitySetResolver.ResolveEntitySetUri; } #endif return(ctx); }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.Execute dynamically /// </summary> /// <typeparam name="TElement">The element type of the wrapped query results</typeparam> /// <param name="context">The context to call execute on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="elementType">The element type of the query results</param> /// <param name="requestUri">The uri to make a request to</param> /// <param name="httpMethod">The HttpMethod to make a request</param> /// <param name="singleResult">Whether expect single item in result</param> /// <param name="operationParameters">Parameter for the request</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void Execute <TElement>(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, Type elementType, System.Uri requestUri, string httpMethod, bool singleResult, WrappedArray <WrappedOperationParameter> operationParameters, Action <WrappedIEnumerable <TElement> > onCompletion) where TElement : WrappedObject { ExceptionUtilities.CheckArgumentNotNull(context, "context"); AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedIEnumerable <TElement> >( continuation, async, () => context.Execute <TElement>(elementType, requestUri, httpMethod, singleResult, operationParameters), c => context.BeginExecute <TElement>(elementType, requestUri, c, null, httpMethod, singleResult, operationParameters), r => context.EndExecute <TElement>(elementType, r), onCompletion); }
public DataServiceContextData GetDataServiceContextData(WrappedDataServiceContext context) { DSClient.DataServiceContext unwrappedContext = (DSClient.DataServiceContext)context.Product; DataServiceContextData data; if (!this.contextDatas.TryGetValue(unwrappedContext, out data)) { throw new TaupoInvalidOperationException("Given data service context is not tracked in this scope."); } return(data); }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.GetReadStream dynamically /// </summary> /// <param name="context">The context to call get read stream on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="entity">The entity to get the read stream for</param> /// <param name="streamName">The name of the stream or null to indicate the default stream</param> /// <param name="args">The wrapped args to the request</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void GetReadStream(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, WrappedEntityInstance entity, string streamName, WrappedObject args, Action <WrappedDataServiceStreamResponse> onCompletion) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); if (streamName == null) { AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedDataServiceStreamResponse>(continuation, async, () => context.GetReadStream(entity, args), c => context.BeginGetReadStream(entity, args, c, null), r => context.EndGetReadStream(r), onCompletion); } else { AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedDataServiceStreamResponse>(continuation, async, () => context.GetReadStream(entity, streamName, args), c => context.BeginGetReadStream(entity, streamName, args, c, null), r => context.EndGetReadStream(r), onCompletion); } }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.SaveChanges dynamically /// </summary> /// <param name="context">The context to save changes on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="options">The save changes options to use or null to use the overload without options</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void SaveChanges(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, SaveChangesOptions?options, Action <WrappedDataServiceResponse> onCompletion) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); if (options == null) { AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedDataServiceResponse>(continuation, async, () => context.SaveChanges(), c => context.BeginSaveChanges(c, null), r => context.EndSaveChanges(r), onCompletion); } else { var wrappedEnum = context.Scope.Wrap <WrappedEnum>(options.Value.ToProductEnum()); AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedDataServiceResponse>(continuation, async, () => context.SaveChanges(wrappedEnum), c => context.BeginSaveChanges(wrappedEnum, c, null), r => context.EndSaveChanges(r), onCompletion); } }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.Execute dynamically /// </summary> /// <typeparam name="TElement">The element type of the wrapped query results</typeparam> /// <param name="context">The context to call execute on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="elementType">The element type of the query results</param> /// <param name="productContinuation">The wrapped continuation token</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void Execute <TElement>(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, Type elementType, WrappedDataServiceQueryContinuation <TElement> productContinuation, Action <WrappedQueryOperationResponse <TElement> > onCompletion) where TElement : WrappedObject { ExceptionUtilities.CheckArgumentNotNull(context, "context"); // because EndExecute is reused for the async version, we need to do some work to get the right return type AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedQueryOperationResponse <TElement> >( continuation, async, () => context.Execute(elementType, productContinuation), c => context.BeginExecute(elementType, productContinuation, c, null), r => new WrappedQueryOperationResponse <TElement>(context.Scope, context.EndExecute <TElement>(elementType, r).Product), onCompletion); }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.Execute dynamically /// </summary> /// <param name="context">The context to call execute on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="requestUri">The uri to make a request to</param> /// <param name="httpMethod">The HttpMethod to make a request</param> /// <param name="operationParameters">Parameter for the request</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void Execute(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, System.Uri requestUri, string httpMethod, WrappedArray <WrappedOperationParameter> operationParameters, Action <WrappedObject> onCompletion) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); // because EndExecute is reused for the async version, we need to do some work to get the right return type AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedObject>( continuation, async, () => context.Execute(requestUri, httpMethod, operationParameters), c => context.BeginExecute(requestUri, c, null, httpMethod, operationParameters), r => new WrappedObject(context.Scope, context.EndExecute(r).Product), onCompletion); }
private void VerifyChangeOnServer(ChangeData change, WrappedDataServiceContext wrappedContext, List <WrappedObject> result) { var linkChange = change as LinkChangeData; int expectedCount = change.State == EntityStates.Deleted ? 0 : 1; if (linkChange != null && linkChange.DescriptorData.TargetDescriptor == null) { expectedCount = 0; } this.Assert.AreEqual(expectedCount, result.Count, "Verify only one entity is returned for the uri representing link or descriptor."); if (expectedCount == 1) { var entity = result.Single(); this.Assert.AreEqual((object)change.ClrTypeForRequery, entity.Product.GetType(), "Verify the CLR type for the query"); if (linkChange != null) { var targetEntity = linkChange.DescriptorData.TargetDescriptor.Entity; ExceptionUtilities.CheckObjectNotNull(targetEntity, "Target was unexpectedly null for link change: {0}", linkChange.ToString()); var targetType = this.GetEntityType(targetEntity.GetType()); var possibleSets = this.ModelSchema.EntityContainers.SelectMany(c => c.EntitySets).Where(s => targetType.IsKindOf(s.EntityType)).ToList(); if (!possibleSets.Any(s => s.Annotations.OfType <EntryIdReplacementAnnotation>().Any(a => a.AppendRequestIdToName))) { var expectedIdentity = linkChange.DescriptorData.TargetDescriptor.Identity; var actualIdentity = wrappedContext.GetEntityDescriptor(entity).Identity; this.Assert.AreEqual(expectedIdentity, actualIdentity, ValueComparer.Instance, "Entity ID did not match for link change: {0}", linkChange.ToString()); } } else if (this.VerifyData) { this.VerifyPropertiesValues((EntityChangeData)change, entity.Product); } } }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.LoadProperty dynamically /// </summary> /// <param name="context">The context to call call load property on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="entity">The entity to load a property on</param> /// <param name="propertyName">The name of the property to load</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void LoadProperty(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, WrappedEntityInstance entity, string propertyName, Action <WrappedQueryOperationResponse> onCompletion) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedQueryOperationResponse>(continuation, async, () => context.LoadProperty(entity, propertyName), c => context.BeginLoadProperty(entity, propertyName, c, null), r => context.EndLoadProperty(r), onCompletion); }
/// <summary> /// Executes SaveChanges on the specified context and with specified options and verifies the results. /// </summary> /// <param name="verifier">The verifier to use for verification.</param> /// <param name="context">The context to verify SaveChanges on.</param> /// <param name="options">The options for saving changes.</param> /// <returns>The response from SaveChanges</returns> public static DSClient.DataServiceResponse VerifySaveChanges(this ISaveChangesVerifier verifier, WrappedDataServiceContext context, SaveChangesOptions options) { DataServiceContextData data = CheckParametersAndGetDataServiceContextData(verifier, context); return(verifier.VerifySaveChanges(data, (DSClient.DataServiceContext)context.Product, options)); }
/// <summary> /// Builds the single variation. /// </summary> /// <param name="contextVariable">The context variable.</param> /// <param name="resultComparerVariable">The result comparer variable.</param> /// <param name="query">The query.</param> /// <param name="dataServiceContext">Wrapped Data Service Context</param> protected virtual void BuildSingleVariation(CodeExpression contextVariable, CodeExpression resultComparerVariable, QueryExpression query, WrappedDataServiceContext dataServiceContext) { DataServiceProtocolVersion maxProtocolVersion = this.workspace.ConceptualModel.GetMaxProtocolVersion(); DataServiceProtocolVersion maxClientProtocolVersion = DataServiceProtocolVersion.Unspecified; #if !WINDOWS_PHONE maxClientProtocolVersion = ((ODataProtocolVersion)dataServiceContext.MaxProtocolVersion.Product).ToTestEnum(); #endif var singleVariationCodeBuilder = this.ClientQuerySingleVariationCodeBuilderResolver.Resolve(query); // TODO: Fix service operation test coverage in Taupo.Clientko if (singleVariationCodeBuilder != null) { var expectedError = this.ClientQueryVersionErrorCalculator.CalculateExpectedClientVersionError(query, !this.IsUri, maxClientProtocolVersion, maxProtocolVersion); var expectedClientErrorValue = ClientQueryCodeGenHelperMethods.BuildClientExpectedErrorExpression(expectedError); singleVariationCodeBuilder.Build(this.CodeBuilder, query, expectedClientErrorValue, contextVariable, resultComparerVariable); } }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.ExecuteBatch dynamically /// </summary> /// <param name="context">The context to call execute batch on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="queries">The queries to execute</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void ExecuteBatch(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, WrappedArray <WrappedDataServiceRequest> queries, Action <WrappedDataServiceResponse> onCompletion) { ExceptionUtilities.CheckArgumentNotNull(context, "context"); AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedDataServiceResponse>(continuation, async, () => context.ExecuteBatch(queries), c => context.BeginExecuteBatch(c, null, queries), r => context.EndExecuteBatch(r), onCompletion); }
/// <summary> /// Creates a query using the clr type and entity set from the given query entity type /// </summary> /// <typeparam name="TElement">The wrapped element type of the query</typeparam> /// <param name="context">The wrapped context</param> /// <param name="queryEntityType">The query entity type</param> /// <returns>The query created using the clr type and entity set name from the query type</returns> public static WrappedDataServiceQuery <TElement> CreateQuery <TElement>(this WrappedDataServiceContext context, QueryEntityType queryEntityType) where TElement : WrappedObject { ExceptionUtilities.CheckArgumentNotNull(context, "context"); ExceptionUtilities.CheckArgumentNotNull(queryEntityType, "queryEntityType"); return(context.CreateQuery <TElement>(queryEntityType.ClrType, queryEntityType.EntitySet.Name)); }
/// <summary> /// Extension method to perform sync/async version of DataServiceContext.Execute dynamically /// </summary> /// <typeparam name="TElement">The element type of the wrapped query results</typeparam> /// <param name="context">The context to call execute on</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="async">A value indicating whether or not to use async API</param> /// <param name="elementType">The element type of the query results</param> /// <param name="requestUri">The uri to make a request to</param> /// <param name="onCompletion">A callback for when the call completes</param> public static void Execute <TElement>(this WrappedDataServiceContext context, IAsyncContinuation continuation, bool async, Type elementType, Uri requestUri, Action <WrappedIEnumerable <TElement> > onCompletion) where TElement : WrappedObject { ExceptionUtilities.CheckArgumentNotNull(context, "context"); AsyncHelpers.InvokeSyncOrAsyncMethodCall <WrappedIEnumerable <TElement> >(continuation, async, () => context.Execute <TElement>(elementType, requestUri), c => context.BeginExecute <TElement>(elementType, requestUri, c, null), r => context.EndExecute <TElement>(elementType, r), onCompletion); }
private void VerifyChangeOnServer(ChangeData change, WrappedDataServiceContext wrappedContext, List<WrappedObject> result) { var linkChange = change as LinkChangeData; int expectedCount = change.State == EntityStates.Deleted ? 0 : 1; if (linkChange != null && linkChange.DescriptorData.TargetDescriptor == null) { expectedCount = 0; } this.Assert.AreEqual(expectedCount, result.Count, "Verify only one entity is returned for the uri representing link or descriptor."); if (expectedCount == 1) { var entity = result.Single(); this.Assert.AreEqual((object)change.ClrTypeForRequery, entity.Product.GetType(), "Verify the CLR type for the query"); if (linkChange != null) { var targetEntity = linkChange.DescriptorData.TargetDescriptor.Entity; ExceptionUtilities.CheckObjectNotNull(targetEntity, "Target was unexpectedly null for link change: {0}", linkChange.ToString()); var targetType = this.GetEntityType(targetEntity.GetType()); var possibleSets = this.ModelSchema.EntityContainers.SelectMany(c => c.EntitySets).Where(s => targetType.IsKindOf(s.EntityType)).ToList(); if (!possibleSets.Any(s => s.Annotations.OfType<EntryIdReplacementAnnotation>().Any(a => a.AppendRequestIdToName))) { var expectedIdentity = linkChange.DescriptorData.TargetDescriptor.Identity; var actualIdentity = wrappedContext.GetEntityDescriptor(entity).Identity; this.Assert.AreEqual(expectedIdentity, actualIdentity, ValueComparer.Instance, "Entity ID did not match for link change: {0}", linkChange.ToString()); } } else if (this.VerifyData) { this.VerifyPropertiesValues((EntityChangeData)change, entity.Product); } } }
private static DataServiceContextData CheckParametersAndGetDataServiceContextData(ISaveChangesVerifier verifier, WrappedDataServiceContext context) { ExceptionUtilities.CheckArgumentNotNull(verifier, "verifier"); ExceptionUtilities.CheckArgumentNotNull(context, "context"); IDataServiceContextTrackingScope trackingScope = context.Scope as IDataServiceContextTrackingScope; ExceptionUtilities.CheckObjectNotNull(trackingScope, "Wrapped data service sontext does not belong to a tracking scope. Cannot obtain DataServiceContextData for verification."); return trackingScope.GetDataServiceContextData(context); }
private static DataServiceContextData CheckParametersAndGetDataServiceContextData(ISaveChangesVerifier verifier, WrappedDataServiceContext context) { ExceptionUtilities.CheckArgumentNotNull(verifier, "verifier"); ExceptionUtilities.CheckArgumentNotNull(context, "context"); IDataServiceContextTrackingScope trackingScope = context.Scope as IDataServiceContextTrackingScope; ExceptionUtilities.CheckObjectNotNull(trackingScope, "Wrapped data service sontext does not belong to a tracking scope. Cannot obtain DataServiceContextData for verification."); return(trackingScope.GetDataServiceContextData(context)); }
/// <summary> /// Executes SaveChanges on the specified context and with specified options and verifies the results. /// </summary> /// <param name="verifier">The verifier to use for verification.</param> /// <param name="context">The context to verify SaveChanges on.</param> /// <param name="options">The options for saving changes.</param> /// <returns>The response from SaveChanges</returns> public static DSClient.DataServiceResponse VerifySaveChanges(this ISaveChangesVerifier verifier, WrappedDataServiceContext context, SaveChangesOptions options) { DataServiceContextData data = CheckParametersAndGetDataServiceContextData(verifier, context); return verifier.VerifySaveChanges(data, (DSClient.DataServiceContext)context.Product, options); }
/// <summary> /// Executes SaveChanges on the specified context and verifies the results. /// </summary> /// <param name="verifier">The verifier to use for verification.</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="context">The context to verify SaveChanges on.</param> /// <param name="options">The options to use, or null for the default</param> /// <param name="onCompletion">The callback to call on completion</param> public static void VerifySaveChanges(this ISaveChangesVerifier verifier, IAsyncContinuation continuation, WrappedDataServiceContext context, SaveChangesOptions?options, Action <IAsyncContinuation, DSClient.DataServiceResponse> onCompletion) { DataServiceContextData data = CheckParametersAndGetDataServiceContextData(verifier, context); verifier.VerifySaveChanges(continuation, data, (DSClient.DataServiceContext)context.Product, options, onCompletion); }
/// <summary> /// Executes SaveChanges on the specified context and verifies the results. /// </summary> /// <param name="verifier">The verifier to use for verification.</param> /// <param name="continuation">The asynchronous continuation</param> /// <param name="context">The context to verify SaveChanges on.</param> /// <param name="options">The options to use, or null for the default</param> /// <param name="onCompletion">The callback to call on completion</param> public static void VerifySaveChanges(this ISaveChangesVerifier verifier, IAsyncContinuation continuation, WrappedDataServiceContext context, SaveChangesOptions? options, Action<IAsyncContinuation, DSClient.DataServiceResponse> onCompletion) { DataServiceContextData data = CheckParametersAndGetDataServiceContextData(verifier, context); verifier.VerifySaveChanges(continuation, data, (DSClient.DataServiceContext)context.Product, options, onCompletion); }
public static WrappedDataServiceCollection <TElement> CreateDataServiceCollection <TElement>(this IWrapperScope wrapperScope, Type clrType, WrappedDataServiceContext context, string entitySetName, Func <DSClient.EntityChangedParams, bool> entityChangedCallback, Func <DSClient.EntityCollectionChangedParams, bool> collectionChangedCallback) where TElement : WrappedObject { ExceptionUtilities.CheckArgumentNotNull(wrapperScope, "wrapperScope"); ExceptionUtilities.CheckArgumentNotNull(context, "context"); ExceptionUtilities.CheckArgumentNotNull(entitySetName, "entitySetName"); Type dataServiceCollectionType = typeof(DSClient.DataServiceCollection <>).MakeGenericType(clrType); ConstructorInfo constructorWithContext = dataServiceCollectionType.GetInstanceConstructor(true, new Type[] { typeof(DSClient.DataServiceContext), typeof(string), typeof(Func <DSClient.EntityChangedParams, bool>), typeof(Func <DSClient.EntityCollectionChangedParams, bool>) }); ExceptionUtilities.CheckObjectNotNull(constructorWithContext, "Could not find constructor"); var collection = constructorWithContext.Invoke(new object[] { context.Product, entitySetName, entityChangedCallback, collectionChangedCallback }); return(wrapperScope.Wrap <WrappedDataServiceCollection <TElement> >(collection)); }