public static KeyExpression ConvertToKeyExpression(ResourceInstanceKey key, Workspace workspace) { ResourceContainer container = workspace.ServiceContainer.ResourceContainers[key.ResourceSetName]; if (container == null) { return(null); } ResourceType type = container.ResourceTypes.FirstOrDefault(rt => rt.Name == key.ResourceTypeName); if (type == null) { return(null); } return(key.CreateKeyExpression(container, type)); }
public KeyExpression GetRandomGeneratedKey(ResourceContainer container, ResourceType type) { KeyExpressions keys; if (!_existingKeyMap.TryGetValue(container, out keys)) { return(null); } if (type == null) { return(keys.Choose()); } return(keys.Where(k => k.ResourceType == type).Choose()); }
public KeyExpressions GetAllGeneratedKeys(ResourceContainer container, ResourceType type) { KeyExpressions keys; if (!_existingKeyMap.TryGetValue(container, out keys)) { return(new KeyExpressions()); } if (type == null) { return(keys); } return(new KeyExpressions(keys.Where(k => k.ResourceType == type))); }
public static AstoriaRequest BuildInsert(Workspace workspace, ResourceContainer container, ResourceType type, HttpStatusCode expectedStatusCode, SerializationFormatKind format, out KeyExpression createdKey) { KeyedResourceInstance newResource = type.CreateRandomResource(container); if (newResource == null) { newResource = ResourceInstanceUtil.CreateKeyedResourceInstanceByClone(container, type); if (newResource == null) { createdKey = null; return(null); } } QueryNode query; if (!type.Key.Properties.Any(p => p.Facets.ServerGenerated) && newResource.ResourceInstanceKey != null) { createdKey = newResource.ResourceInstanceKey.CreateKeyExpression(container, type); query = ContainmentUtil.BuildCanonicalQuery(createdKey, true); } else { createdKey = null; // the key is unknown, must be server generated // in this case, lets hope that containment is a non-issue query = Query.From(Exp.Variable(container)) .Select(); if (!container.Facets.TopLevelAccess && expectedStatusCode == HttpStatusCode.Created) { expectedStatusCode = HttpStatusCode.BadRequest; } } AstoriaRequest request = workspace.CreateRequest(); request.Verb = RequestVerb.Post; request.Query = query; request.UpdateTree = newResource; request.ExpectedStatusCode = expectedStatusCode; request.Format = format; return(request); }
protected void SetupServiceOperations(Workspace workspace, ResourceContainer resourceContainer, ResourceType resourceType) { if (serviceOperations == null) { serviceOperations = new List <ServiceOperation>(); } #region Single level Expand ServiceOperation serviceOperation = Resource.ServiceOperation(String.Format("Return{0}OfTWithExpandOneLevel", resourceType.Name), resourceContainer, resourceType); serviceOperation.ExpectedTypeName = resourceType.Name; StringBuilder includeString = new StringBuilder(); foreach (ResourceProperty navigationProperty in resourceType.Properties.Cast <ResourceProperty>().Where(rp => rp.IsNavigation)) { includeString.AppendFormat(".Include(\"{0}\")", navigationProperty.Name); } serviceOperation.ServiceOpCode = String.Format(Workspace.IQueryableOfTWithOneIncludeServiceOpTemplate, resourceType.Name, resourceContainer.Name, workspace.ContextNamespace, resourceType.Name, includeString.ToString()); #endregion #region Multiple level Expand includeString = new StringBuilder(); string dottedExpandPath = GetDottedPath(resourceType); ServiceOperation serviceOperation2LevelExpand = Resource.ServiceOperation(String.Format("Return{0}OfTWithExpand{1}Level", resourceType.Name, expandDepth), resourceContainer, resourceType); if (dottedExpandPath.Length > 0) { includeString.AppendFormat(".Include(\"{0}\")", dottedExpandPath); serviceOperation2LevelExpand.ServiceOpCode = String.Format(Workspace.IQueryableOfTWithNIncludeServiceOpTemplate, resourceType.Name, resourceContainer.Name, workspace.ContextNamespace, resourceType.Name, includeString.ToString(), expandDepth); #endregion if (!serviceOperations.Any(sop => sop.Name == serviceOperation2LevelExpand.Name) && (!workspace.ServiceContainer.Any(sop => sop.Name == serviceOperation2LevelExpand.Name)) ) { serviceOperations.Add(serviceOperation2LevelExpand); } } if (!serviceOperations.Any(sop => sop.Name == serviceOperation.Name) && (!workspace.ServiceContainer.Any(sop => sop.Name == serviceOperation.Name)) ) { serviceOperations.Add(serviceOperation); } expandDepth = 0; typesTraversed = new List <string>(); // }
public static KeyExpressions GetAllExistingKeys(Workspace w, ResourceContainer resourceContainer, ResourceType resourceType) { IEnumerable <ContainmentAttribute> attributes = GetContainmentAttributes(w.ServiceContainer, ca => ca.ChildContainer == resourceContainer); // should we pick one path at random? just use the first? determine which is shortest? ContainmentAttribute att = attributes.FirstOrDefault(); if (att == null) { QueryNode query = Query.From( Exp.Variable(resourceContainer)) .Select(); if (resourceType != null) { query = query.OfType(resourceType); } return(w.GetAllExistingKeys(query, resourceContainer)); } // recursively get all the parent container's keys // since we don't know the exact parent type, don't use one // KeyExpressions parentKeys = GetAllExistingKeys(w, att.ParentContainer, null); // we're doing some extra work by re-determining the parent key's access path, // but it would be hard to keep it around // KeyExpressions childKeys = new KeyExpressions(); foreach (KeyExpression parentKey in parentKeys) { // we don't necessarily need a canonical path QueryNode q = BuildQuery(parentKey, false); q = q.Nav(att.ParentNavigationProperty.Property()).Select(); if (resourceType != null) { q = q.OfType(resourceType); } foreach (KeyExpression childKey in w.GetAllExistingKeys(q, resourceContainer)) { childKeys.Add(childKey); } } return(childKeys); }
protected void UpdateAction(ResourceType resourceType, ResourceContainer resourceContainer, object entity) { AstoriaTestLog.WriteLine("Updating entity set :{0} , entity type :{1}", resourceContainer.Name, resourceType.Name); //Change any of the properties that make up the Etag #if !ClientSKUFramework IEdmEntityType entityType = DataServiceMetadata.GetEntityType(entity); foreach (string eTagProperty in entityType.EtagProperties()) { Type propertyType = entity.GetType().GetProperty(eTagProperty).PropertyType; object newValue = propertyType.GetTypedValue(eTagProperty, resourceType.Properties[eTagProperty].Facets.MaxSize); //entity.SetPropertyValue(eTagProperty, newValue); } #endif CurrentContext.UpdateObject(entity); ExecuteAndValidate(() => { CurrentContext.SaveChanges(SaveChangeOption); }); }
public override IQueryable ResourceContainerToQueryable(ResourceContainer container) { //Get Lts Type Type type = this._resourceTypeToWorkspaceTypeList[container.BaseType]; DataContext context = new DataContext(this.Database.DatabaseConnectionString); MethodInfo method = context.GetType().GetMethod("GetTable", new Type[] { }); MethodInfo genMethod = method.MakeGenericMethod(new Type[] { type }); object o = genMethod.Invoke(context, new object[] { }); if (container.HasInterceptorExpression) { o = ApplyQueryInterceptorExpression(container, o as IQueryable); } return((IQueryable)o); }
public void ChooseFrom() { bool bFound = false; while (!bFound) { ResourceContainer container = _w.ServiceContainer.ResourceContainers.Choose(); if (container.BaseType.ClrType.IsAbstract == true) { continue; } ; if (container.Name.Contains("Failure")) { continue; } if (container.Name.Contains("CustomerDemographics")) { continue; } if (container.Name.Contains("DataKey_Bit")) { continue; } if (container.Name.Contains("Baseline")) { continue; } if (container.Name.Contains("Uninvestigated")) { continue; } //check for CanInsert/CanDelete ResourceType rt = container.ResourceTypes.FirstOrDefault(); this.Result = rt; this.ResultContainer = container; this.CanInsert = CanInsertResource(rt); this.CanDelete = CanDeleteResource(rt); bFound = true; } this.Disabled = true; //Done }
public static void SimpleTestOnSpecificContainerType(Workspaces workspaces, string containerName, string resourceTypeName, Action <ResourceContainer, ResourceType> action) { bool testRun = false; bool testSkipped = false; foreach (Workspace workspace in workspaces) { ResourceType resourceType = null; ResourceContainer container = null; IEnumerable <ResourceContainer> containers = workspace.ServiceContainer.ResourceContainers.Where(rc => rc.Name == containerName); if (containers.Count() > 0) { container = containers.First(); } if (container != null) { if (!container.Workspace.Settings.SupportsUpdate) { testSkipped = true; continue; } IEnumerable <ResourceType> resourceTypes = container.ResourceTypes.Where(rt => rt.Name == resourceTypeName).ToList(); if (resourceTypes.Count() > 0) { resourceType = resourceTypes.First(); } action.Invoke(container, resourceType); testRun = true; } } //Test likely to be more of a one off type of test on a specific resourceType if ((testRun == false) && (!testSkipped)) { throw new TestFailedException("Couldn't find a container:" + containerName + " with a type:" + resourceTypeName + " to run test with"); } else { if (testSkipped) { throw new TestSkippedException("Container: " + containerName + " in this workspace does not support update"); } } }
public static void ExecuteLinq(Workspace workspace, ExpNode q, ResourceContainer container, bool bSingle, ExpNode altq) { System.Uri uri = new Uri(workspace.ServiceUri); WebDataCtxWrapper ctx = new WebDataCtxWrapper(uri); ctx.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; ctx.MergeOption = MergeOption.NoTracking; Type resType = container.BaseType.ClientClrType; ResolveClientType(workspace, ctx, resType); Type cType = typeof(WebDataCtxWrapper); MethodInfo mi = cType.GetMethod("CreateQuery", new Type[] { typeof(string) }); Type pType = container.BaseType.ClientClrType; MethodInfo miConstructed = mi.MakeGenericMethod(pType); string uri2 = container.Name; AstoriaTestLog.WriteLineIgnore(workspace.ServiceUri + "/" + uri2); object[] args = { uri2 }; object query = miConstructed.Invoke(ctx, args); LinqQueryBuilder lb = new LinqQueryBuilder(workspace, (IQueryable)query); string uri3 = lb.Build(q); AstoriaTestLog.WriteLineIgnore("Linq expression: " + lb.QueryExpression); //if (bSingle) //{ // var single = lb.QueryResultSingle; // VerifyLinqSingle(workspace, altq, single, container); //} //else //{ var queryable = lb.QueryResult; VerifyLinq(workspace, q, (IQueryable)queryable); //} }
private ContainmentAttribute(bool canonical, bool topLevelAccess, ResourceContainer parent, ResourceContainer child) : base(canonical ? "CanonicalAccessPath" : "AccessPath") { parent.Workspace.Settings.HasContainment = true; this.ParentContainer = parent; this.ChildContainer = child; this.Canonical = canonical; this.TopLevelAccess = topLevelAccess; this.KeyMapping = new Dictionary <string, string>(); this.InferProperties(); if (canonical) { this.namedParams.Add("TopLevelAccess", topLevelAccess.ToString().ToLowerInvariant()); } ParentNavigationProperty.Facets.Add(NodeFacet.CanonicalAccessPath(Canonical)); ChildContainer.BaseType.Facets.Add(NodeFacet.TopLevelAccess(topLevelAccess)); }
public AstoriaRequest EntitySetTopLevelWithSingleExpand(out ResourceContainer container, out ResourceProperty property) { container = _workspace.ServiceContainer.ResourceContainers .Where(c => c.ResourceTypes.Any(rt => rt.Properties.OfType <ResourceProperty>().Any(p => p.IsNavigation && p.Type is CollectionType))).Choose(); var properties = container.BaseType.Properties.OfType <ResourceProperty>(). Where(p => p.IsNavigation); if (properties.Count() > 0) { property = properties.Choose(); return(EntitySetTopLevelWithSingleExpand(container, property)); } else { container = null; property = null; return(null); } }
internal static ResourceInstanceKey CreateUniqueKey(ResourceContainer container, ResourceType resType, KeyExpressions relatedForeignKeys, KeyExpressions existingKeys) { KeyExpressions possibleRelatedForeignKeys = new KeyExpressions(); Workspace workspace = container.Workspace; int keysGenerated = 0; bool keyTrying = true; ResourceInstanceKey resourceInstanceKey = null; do { possibleRelatedForeignKeys = new KeyExpressions(); resourceInstanceKey = TryCreateUniqueResourceInstanceKey(container, resType, possibleRelatedForeignKeys); KeyExpression keyExpression = resourceInstanceKey.CreateKeyExpression(container, resType); // need to make sure its not a duplicate // if (existingKeys == null) { KeyedResourceInstance o = workspace.GetSingleResourceByKey(keyExpression); if (o == null) { keyTrying = false; } } else { keyTrying = existingKeys.Contains(keyExpression); } keysGenerated++; if (keysGenerated > 25) { throw new Microsoft.Test.ModuleCore.TestFailedException("Unable to create a unique key"); } }while (keyTrying); relatedForeignKeys.Add(possibleRelatedForeignKeys); return(resourceInstanceKey); }
protected object InsertAction(ResourceType resourceType, ResourceContainer resourceContainer, Workspace workspace) { AstoriaTestLog.WriteLine("Inserting into entity set :{0} , entity type :{1}", resourceContainer.Name, resourceType.Name); object entity = null; if (resourceType.Name == "AllTypesComplexEntity") { IQueryable results = CurrentContext.ExecuteOfT(resourceType.ClientClrType, new Uri(String.Format("{0}?$top=1", resourceContainer.Name), UriKind.RelativeOrAbsolute)).AsQueryable(); IEnumerator enumerat = results.GetEnumerator(); enumerat.MoveNext(); entity = enumerat.Current; ResourceProperty keyProperty = resourceType.Properties.Cast <ResourceProperty>().First(prop => prop.PrimaryKey != null); entity.GetType().GetProperty(keyProperty.Name).SetValue(entity, null, null); } else { entity = resourceType.CreateInstance(false); } CurrentContext.AddObject(resourceContainer.Name, entity); CurrentContext.EnsureInsert(entity, resourceType); EnsureInsert(CurrentContext.UnderlyingContext, entity, resourceContainer.Name, workspace, ""); ExecuteAndValidate(() => { CurrentContext.SaveChanges(SaveChangeOption); }); return(entity); }
public virtual void RunModel() { QueryModel model = new QueryModel(_workspace, _kind, null); ModelEngine engine = new ModelEngine(model); engine.Options.WeightScheme = WeightScheme.Custom; engine.Options.Timeout = 100; engine.RunUntil(delegate() { return(model.Actions.Accessed > 5); }); _query = model.QueryResult; _container = model.ResContainer; _pType = model.ResultType; if (_query != null || _pType != null) { switch (_queryType) { case "server": VerifyServer(_query); break; case "client": VerifyClient(model); break; case "linq": VerifyClientLinq(model); break; } } }
public static AstoriaRequest BuildInsert(Workspace workspace, ResourceContainer container, ResourceType type) { return(BuildInsert(workspace, container, type, HttpStatusCode.Created, SerializationFormatKind.Default)); }
public static AstoriaRequest BuildRandomRequest(Workspace workspace, RequestVerb verb, SerializationFormatKind format) { IEnumerable <ResourceContainer> safeContainers = workspace.ServiceContainer.ResourceContainers .Where(c => IsSafeOperation(verb, c)); if (verb != RequestVerb.Get) { safeContainers = safeContainers.Where(c => c.ResourceTypes.Any(t => IsSafeOperation(verb, c, t))); } fxList <ResourceContainer> containers = new fxList <ResourceContainer>(safeContainers); if (!containers.Any()) { return(null); } AstoriaRequest request = null; while (request == null && containers.Any()) { ResourceContainer container = null; ResourceType type = null; KeyExpression key = null; while (container == null && containers.Any()) { container = containers.Choose(); if (verb == RequestVerb.Get) { key = workspace.GetRandomExistingKey(container); if (key == null) { containers.Remove(container); container = null; } } else { fxList <ResourceType> types = new fxList <ResourceType>(container.ResourceTypes.Where(t => IsSafeOperation(verb, container, t))); if (!types.Any()) { containers.Remove(container); container = null; } if (verb != RequestVerb.Delete) { type = types.Choose(); } else { while (key == null && types.Any()) { type = types.Choose(); key = workspace.GetRandomExistingKey(container, type); if (key == null) { types.Remove(type); } } if (key == null) { containers.Remove(container); container = null; } } } } // if we ran out of containers before finding one that would work // if (container == null) { return(null); } // if the Build___ method returns null, we'll come back around with a different container/key // switch (verb) { case RequestVerb.Get: request = BuildGet(workspace, key, HttpStatusCode.OK, format); break; case RequestVerb.Post: request = BuildInsert(workspace, container, type, HttpStatusCode.Created, format); break; case RequestVerb.Put: case RequestVerb.Patch: request = BuildUpdate(workspace, container, type, (verb == RequestVerb.Put), HttpStatusCode.NoContent, format); break; case RequestVerb.Delete: request = BuildDelete(workspace, key, HttpStatusCode.NoContent, format); break; default: throw new ArgumentException("Unsupported verb: " + verb.ToString()); } } // might be null, but we did our best // return(request); }
public static bool IsSafeLinkOperation(RequestVerb verb, ResourceContainer container, ResourceProperty property) { if (!property.IsNavigation) { return(false); } if (property.Facets.UnsafeLinkOperations.Contains(verb)) { return(false); } if (verb == RequestVerb.Get) { return(true); } // astoria-level check switch (verb) { case RequestVerb.Patch: case RequestVerb.Put: if (property.OtherAssociationEnd.Multiplicity == Multiplicity.Many) { return(false); } break; case RequestVerb.Post: if (property.OtherAssociationEnd.Multiplicity != Multiplicity.Many) { return(false); } break; case RequestVerb.Delete: if (property.OtherAssociationEnd.Multiplicity == Multiplicity.One) { return(false); } break; default: return(false); } //// EF/DB level check if (container.Workspace.Database != null) { // would changing this nav-prop affect any foreign keys List <NodeProperty> affectedProperties = new List <NodeProperty>(); foreach (NodeProperty p in property.ResourceType.Properties) { if (!p.ForeignKeys.Any()) { continue; } ResourceType relatedType = (p.ForeignKeys.First().PrimaryKey.Properties.First() as ResourceProperty).ResourceType; if (relatedType == property.OtherAssociationEnd.ResourceType) { affectedProperties.Add(p); } } foreach (NodeProperty p in property.OtherAssociationEnd.ResourceType.Properties) { if (!p.ForeignKeys.Any()) { continue; } ResourceType relatedType = (p.ForeignKeys.First().PrimaryKey.Properties.First() as ResourceProperty).ResourceType; if (relatedType == property.ResourceType) { affectedProperties.Add(p); } } // can't change primary key by changing nav-prop if (affectedProperties.Any(p => p.PrimaryKey != null)) { return(false); } if (verb == RequestVerb.Delete && affectedProperties.Any(p => !p.Facets.Nullable)) { return(false); } if (container.Workspace.DataLayerProviderKind == DataLayerProviderKind.Edm && (verb == RequestVerb.Put || verb == RequestVerb.Patch)) { // EF: updating self-reference causes a null-reference in the mapping layer if (property.Type is ResourceType && property.OtherAssociationEnd.ResourceType == property.ResourceType) { return(false); } } } return(true); }
public static bool IsSafeOperation(RequestVerb verb, ResourceContainer container, ResourceType type) { switch (verb) { case RequestVerb.Delete: if (!type.IsInsertable) { return(false); } if (type.Associations.Any()) { return(false); } if (type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.IsStoreBlob)) { return(false); } return(true); case RequestVerb.Patch: if (type.Facets.AbstractType) { return(false); } if (!type.IsInsertable) { return(false); } if (type.IsAssociationEntity) { return(false); } if (type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.IsStoreBlob)) { return(false); } return(true); case RequestVerb.Put: if (type.Facets.AbstractType) { return(false); } if (!type.IsInsertable) { return(false); } if (type.IsAssociationEntity) { return(false); } if (type.Properties.Any(p => p.Facets.IsIdentity)) { return(false); } if (type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.IsStoreBlob)) { return(false); } return(true); case RequestVerb.Post: if (type.Facets.AbstractType) { return(false); } if (!type.IsInsertable) { return(false); } if (type.IsAssociationEntity) { return(false); } if (type.IsChildRefEntity) { return(false); } if (type.Associations.Any(ra => ra.Ends.Any(end => end.ResourceType.IsAssociationEntity))) { return(false); } return(true); } return(true); }
public static bool IsSafeOperation(RequestVerb verb, ResourceContainer container) { if (container is ServiceOperation) { ServiceOperation op = container as ServiceOperation; return(verb == op.Verb && verb == RequestVerb.Get); //for now POST always means insert } if (container.Name == "Invoices" && (container.Workspace.DataLayerProviderKind == DataLayerProviderKind.NonClr || container.Workspace.DataLayerProviderKind == DataLayerProviderKind.InMemoryLinq)) { return(false); } switch (verb) { case RequestVerb.Delete: if (container.Name.Equals("DataKey_Bit")) { return(false); } if (container.Name.Equals("ComputerDetails")) { return(false); } if (!container.ResourceTypes.All(type => IsSafeOperation(verb, container, type))) { return(false); } break; case RequestVerb.Post: if (container.Name.Equals("Shippers")) { return(false); } if (container.Name.Equals("Employees")) { return(false); } if (container.Name.Equals("Order_Details")) { return(false); } if (container.Name.Equals("ProjectSet")) { return(false); } if (container.Name.Equals("DataKey_Bit")) { return(false); } if (container.Name.Equals("Vehicles")) { return(false); } if (container.Name.Equals("People")) { return(false); } if (container.Name.Equals("Computers")) { return(false); } if (container.Name.Equals("Workers")) { return(false); } if (!container.ResourceTypes.All(type => IsSafeOperation(verb, container, type))) { return(false); } break; } return(true); }
public static AstoriaRequest BuildUpdate(Workspace workspace, ResourceContainer container, ResourceType resourceType, bool replace, HttpStatusCode expectedStatusCode, SerializationFormatKind format, out KeyExpression modifiedKey) { modifiedKey = workspace.GetRandomExistingKey(container, resourceType); return(BuildUpdate(workspace, modifiedKey, replace, expectedStatusCode, format)); }
public static AstoriaRequest BuildUpdate(Workspace workspace, KeyExpression modifiedKey, bool replace, HttpStatusCode expectedStatusCode, SerializationFormatKind format) { if (modifiedKey == null) { return(null); } ResourceContainer container = modifiedKey.ResourceContainer; ResourceType resourceType = modifiedKey.ResourceType; if (replace && resourceType.Properties.Any(p => p.Facets.IsIdentity)) { return(null); } string keyString = UriQueryBuilder.CreateKeyString(modifiedKey, false); if (expectedStatusCode == HttpStatusCode.NoContent && (keyString.Contains("/") || keyString.Contains(Uri.EscapeDataString("/")))) { expectedStatusCode = HttpStatusCode.BadRequest; } QueryNode query = ContainmentUtil.BuildCanonicalQuery(modifiedKey); List <ResourceInstanceProperty> properties = new List <ResourceInstanceProperty>(); string[] propertiesToSkip; //Skip because setting the birthdate to a random Datetime won't work due to contraints //if (resourceType.Name == "Employees") // propertiesToSkip = new string[] { "BirthDate" }; ////Skipping because it has some weird constraint on it //else if (resourceType.Name == "Order_Details") // propertiesToSkip = new string[] { "Discount" }; //else // propertiesToSkip = new string[] { }; foreach (ResourceProperty resourceProperty in resourceType.Properties.OfType <ResourceProperty>() .Where(p => !p.IsNavigation && p.PrimaryKey == null && !p.Facets.IsIdentity)) //&& !p.IsComplexType //&& !propertiesToSkip.Contains(p.Name))) { properties.Add(resourceProperty.CreateRandomResourceInstanceProperty()); } if (!properties.Any()) { return(null); } KeyedResourceInstance resourceInstance = new KeyedResourceInstance( ResourceInstanceKey.ConstructResourceInstanceKey(modifiedKey), properties.ToArray()); AstoriaRequest request = workspace.CreateRequest(); request.Verb = replace ? RequestVerb.Put : RequestVerb.Patch; request.Query = query; request.UpdateTree = resourceInstance; request.ExpectedStatusCode = expectedStatusCode; request.Format = format; if (modifiedKey.ResourceType.Properties.Any(p => p.Facets.ConcurrencyModeFixed)) { request.Headers[ConcurrencyUtil.IfMatchHeader] = modifiedKey.ETag; request.ETagHeaderExpected = true; } return(request); }
protected override void Verify() { if (!Applies(Response)) { return; } // build a common payload for the insert // CommonPayload insertPayload = Response.Request.CommonPayload; // get the entity that was inserted PayloadObject inserted; if (!TryGetSingleObjectFromPayload(insertPayload, out inserted)) { ResponseVerification.LogFailure(Response, new Exception("Insert request payload did not contain a single entity")); } // determine the type based on what was inserted ResourceType type = Response.Workspace.ServiceContainer.ResourceTypes.Single(rt => inserted.Type.Equals(rt.Namespace + "." + rt.Name)); // get the entity that was returned PayloadObject returned; if (!TryGetSingleObjectFromPayload(Response.CommonPayload, out returned)) { if (Versioning.Server.SupportsLiveFeatures) { string preferHeader; if (Response.Request.Headers.TryGetValue("prefer", out preferHeader) && preferHeader == "return=minimal") { return; } } ResponseVerification.LogFailure(Response, new Exception("Insert response payload did not contain a single entity")); } // verify that the inserted and returned entities are equivalent VerifyInsertResponse(type, inserted, returned); // re-query the entity Workspace workspace = Response.Workspace; AstoriaRequest queryRequest = workspace.CreateRequest(); if (type.Properties.Any(p => p.Facets.ConcurrencyModeFixed)) { queryRequest.ETagHeaderExpected = true; } if (type.Key.Properties.Any(p => p.Type == Clr.Types.DateTime)) { // this will blow up for MEST, but we don't currently have any datetime key + MEST types ResourceContainer container = Response.Workspace.ServiceContainer.ResourceContainers.Single(rc => !(rc is ServiceOperation) && rc.ResourceTypes.Contains(type)); queryRequest.Query = ContainmentUtil.BuildCanonicalQuery(ConcurrencyUtil.ConstructKey(container, returned)); } else { queryRequest.URI = Uri.UnescapeDataString(returned.AbsoluteUri); if (queryRequest.URI.Contains("E+")) { queryRequest.URI = queryRequest.URI.Replace("E+", "E"); } if (queryRequest.URI.Contains("e+")) { queryRequest.URI = queryRequest.URI.Replace("e+", "e"); } } AstoriaResponse queryResponse = queryRequest.GetResponse(); if (queryResponse.ActualStatusCode == HttpStatusCode.BadRequest) { // try it as a filter instead (possibly caused by the URI being too long) // this will blow up for MEST ResourceContainer container = Response.Workspace.ServiceContainer.ResourceContainers .Single(rc => !(rc is ServiceOperation) && rc.ResourceTypes.Contains(type)); KeyExpression key = ConcurrencyUtil.ConstructKey(container, returned); queryRequest = workspace.CreateRequest(Query.From(Exp.Variable(container)).Where(key.Predicate)); queryResponse = queryRequest.GetResponse(); } queryResponse.Verify(); // get the entity from the query PayloadObject queried; if (!TryGetSingleObjectFromPayload(queryResponse.CommonPayload, out queried)) { ResponseVerification.LogFailure(queryResponse, new Exception("Query response payload did not contain a single entity")); } // ensure that the entity did not change between the insert and the re-query VerifyQueryResponse(type, returned, queried); }
public AstoriaRequest EntitySetTopLevel(out ResourceContainer container) { container = _workspace.ServiceContainer.ResourceContainers.Choose(); return(EntitySetTopLevel(container)); }
public static AstoriaRequest BuildGet(Workspace workspace, ResourceContainer container) { return(BuildGet(workspace, container, HttpStatusCode.OK, SerializationFormatKind.Default)); }
public ContainmentAttribute(ResourceContainer parent, ResourceContainer child) : this(false, true, parent, child) { }
public ContainmentAttribute(ResourceContainer parent, ResourceContainer child, bool topLevelAccess) : this(true, topLevelAccess, parent, child) { }
public ServiceOperation(String name, ResourceContainer container, ResourceType baseType, params Node[] nodes) : base(name, baseType, nodes) { this.Container = container; this.BackingType = ServiceOpBackingType.EntitySet; }
private bool Skip(ResourceContainer container) { return(false); }