Esempio n. 1
0
        /// <summary>
        /// Implements IDataInserter.AddAssociation by creating a PUT/POST $ref request using cross-referencing, and adds it to the batch
        /// </summary>
        /// <param name="parent">Update tree of parent, must have already been added using AddEntity</param>
        /// <param name="property">Navigation property for the association</param>
        /// <param name="child">Update tree of child, must have already been added using AddEntity</param>
        public void AddAssociation(KeyedResourceInstance parent, ResourceProperty property, KeyedResourceInstance child)
        {
            // determine which verb to use
            //
            RequestVerb verb;
            if (property.OtherAssociationEnd.Multiplicity == Multiplicity.Many)
                verb = RequestVerb.Post;
            else
                verb = RequestVerb.Put;

            // create the request
            //
            AstoriaRequest request = workspace.CreateRequest();
            request.Verb = verb;

            // use content-id cross referencing to link them
            //
            string parentContentId = contentIDMap[parent];
            string childContentId = contentIDMap[child];

            request.URI = "$" + parentContentId + "/" + property.Name + "/$ref";
            request.Payload = "<adsm:uri xmlns:adsm=\"http://docs.oasis-open.org/odata/ns/metadata\">$" + childContentId + "</adsm:uri>";

            // add it to the queue
            //
            queue.Add(request);

            // fire the event
            //
            if (this.OnAddingAssociation != null)
                OnAddingAssociation(parent, property, child);
        }
Esempio n. 2
0
        /// <summary>
        /// Implements IDataInserter.AddEntity by creating a POST-based insert request and adding it to the batch queue
        /// </summary>
        /// <param name="key">Key expression for new entity</param>
        /// <param name="entity">Update tree for new entity</param>
        public void AddEntity(KeyExpression key, KeyedResourceInstance entity)
        {
            // build the request
            //
            ExpNode containerQuery = ContainmentUtil.BuildCanonicalQuery(key, true);
            AstoriaRequest request = workspace.CreateRequest(containerQuery, entity, RequestVerb.Post);

            // set ETagHeaderExpected appropriately
            if (key.ResourceType.Properties.Any(p => p.Facets.ConcurrencyModeFixed))
                request.ETagHeaderExpected = true;

            // add it to the queue
            //
            queue.Add(request);

            // store the content-id
            //
            contentIDMap[entity] = request.Headers["Content-ID"];

            // fire the event
            //
            if (this.OnAddingEntity != null)
                OnAddingEntity(key, entity);
        }
        private void CreateEntryElement(KeyedResourceInstance keyedResourceInstance, XmlNode parentNode)
        {
            currentResource = keyedResourceInstance;
            XmlElement entryElement = CreateBasicEntryElement(keyedResourceInstance, parentNode);

            //string relativeParentKey = null;
            //Add the Id if there is one

            if (this.RequestVerb != RequestVerb.Post)
            {
                if (keyedResourceInstance.ResourceInstanceKey != null)
                {
                    XmlElement idNode = CreateIdElement(keyedResourceInstance);
                    entryElement.AppendChild(idNode);
                }
            }

            
            ResourceType type = Workspace.ServiceContainer.ResourceTypes.Single(rt => rt.Name == keyedResourceInstance.TypeName);

            XmlElement propertiesNode = CreateDataWebMetadataElement("properties");

            IEnumerable<ResourceInstanceProperty> properties = keyedResourceInstance.Properties;
            if (this.RequestVerb == RequestVerb.Post && keyedResourceInstance.ResourceInstanceKey != null)
                properties = keyedResourceInstance.ResourceInstanceKey.KeyProperties.Union(properties);

            foreach (ResourceInstanceProperty property in properties)
            {
                if (property is ResourceInstanceSimpleProperty)
                {
                    ResourceInstanceSimpleProperty simpleResourceProperty = property as ResourceInstanceSimpleProperty;
                    VisitResourceInstanceSimpleProperty(simpleResourceProperty, propertiesNode);
                }
                else if (property is ResourceInstanceComplexProperty)
                {
                    ResourceInstanceComplexProperty complexResourceProperty = property as ResourceInstanceComplexProperty;

                    if (complexResourceProperty.ComplexResourceInstance == null)
                    {
                        VisitResourceInstanceComplexProperty(complexResourceProperty, propertiesNode);
                    }
                    else
                    {
                        VisitResourceInstanceComplexProperty(complexResourceProperty, propertiesNode);
                    }
                }
                else if (property is ResourceInstanceNavProperty)
                {
                    ResourceInstanceNavProperty navigationProperty = property as ResourceInstanceNavProperty;
                    VisitResourceNavigationProperty(navigationProperty, entryElement);
                }
            }

            if (propertiesNode.ChildNodes.Count > 0)
            {
                if (!type.Facets.HasStream)
                {
                    XmlElement contentNode = CreateAtomElement("content");
                    XmlAttribute contentTypeAttribute = CreateAtomAttribute("type");
                    contentTypeAttribute.Value = RequestUtil.RandomizeContentTypeCapitalization("application/xml");
                    contentNode.Attributes.Append(contentTypeAttribute);
                    contentNode.AppendChild(propertiesNode);
                    entryElement.AppendChild(contentNode);
                }
                else
                {
                    entryElement.AppendChild(propertiesNode);
                }
            }

            if (EntryElementCallback != null)
                EntryElementCallback(entryElement);
        }
        private bool CreateKeyedResourceInstance(ResourceContainer container, ResourceType resourceType, out KeyExpression key, out KeyedResourceInstance newResource)
        {
            int retryCount = 5;

            if (!_existingKeyMap.Keys.Contains(container))
                _existingKeyMap.Add(container, new KeyExpressions());

            newResource = resourceType.CreateRandomResource(container, new KeyExpressions(), false); // should not make request
            key = newResource.ResourceInstanceKey.CreateKeyExpression(container, resourceType);

            while (_existingKeyMap[container].Contains(key) && retryCount > 0)
            {
                newResource.ResourceInstanceKey = ResourceInstanceUtil.CreateUniqueKey(container, resourceType, new KeyExpressions(), new KeyExpressions());
                key = newResource.ResourceInstanceKey.CreateKeyExpression(container, resourceType);
                retryCount--;
            }

            if (retryCount == 0)
            {
                newResource = null;
                key = null;
                return false;
            }

            _existingKeyMap[container].Add(key);
            _existingEntityMap[key] = newResource;
            return true;
        }
        /// <summary>
        /// Implements IDataInserter.AddAssociation by generating the appropriate IUpdatable.AddReferenceToCollection or IUpdatable.SetReference call
        /// </summary>
        /// <param name="parent">Update tree of parent, must have already been added using AddEntity</param>
        /// <param name="property">Navigation property for the association</param>
        /// <param name="child">Update tree of child, must have already been added using AddEntity</param>
        public void AddAssociation(KeyedResourceInstance parent, ResourceProperty property, KeyedResourceInstance child)
        {
            // look up the object names for these entities
            //
            string parentObjectName = entityListName + "[" + entityIDs[parent] + "]";
            string childObjectName = entityListName + "[" + entityIDs[child] + "]";

            // code-gen the appropriate IUpdatable call
            //
            code.AppendLine("//Adding association");
            if (property.OtherAssociationEnd.Multiplicity == Multiplicity.Many)
                code.AppendLine("updatable.AddReferenceToCollection(" + parentObjectName + ", \"" + property.Name + "\", " + childObjectName + ");");
            else
                code.AppendLine("updatable.SetReference(" + parentObjectName + ", \"" + property.Name + "\", " + childObjectName + ");");
            code.AppendLine();

            // Fire the event
            //
            if (this.OnAddingAssociation != null)
                OnAddingAssociation(parent, property, child);

            // ensure that a later Flush/Close will write the SaveChanges call
            changesSaved = false;
        }
        private string GetResourceType(KeyedResourceInstance e)
        {
            string resourceType = e.ResourceSetName;
            if (resourceType == null)
                resourceType = e.ResourceInstanceKey.ResourceSetName;

            return resourceType;
        }
Esempio n. 7
0
        private RowEntityType AddNewEntity(KeyedResourceInstance updateTree, ResourceType entityType)
        {
            List<RowEntityType> resourceList = _resources[updateTree.ResourceSetName];
            RowEntityType newResource = new RowEntityType(updateTree.ResourceSetName, updateTree.TypeName);

            foreach (ResourceInstanceProperty keyProperty in updateTree.KeyProperties)
            {
                ResourceInstanceSimpleProperty tempProperty = (ResourceInstanceSimpleProperty)keyProperty;
                newResource.Properties.Add(tempProperty.Name, tempProperty.PropertyValue);
            }

            AddProperties(updateTree, newResource);

            if (entityType != null)
                AddNavigationProperties(entityType, newResource);

            resourceList.Add(newResource);

            return newResource;
        }
Esempio n. 8
0
        internal static KeyedResourceInstance CreateKeyedResourceInstanceByExactClone(ResourceContainer container, ResourceType resourceType, object dataObject)
        {
            List<ResourceInstanceProperty> properties = new List<ResourceInstanceProperty>();
            List<ResourceInstanceProperty> keyProperties = new List<ResourceInstanceProperty>();
            properties.AddRange(CloneObjectToResourceInstanceProperties(resourceType.Properties.OfType<ResourceProperty>().Where(rp => rp.PrimaryKey == null && rp.IsNavigation == false), dataObject));
            keyProperties.AddRange(CloneObjectToResourceInstanceProperties(resourceType.Properties.OfType<ResourceProperty>().Where(rp => rp.PrimaryKey != null && rp.IsNavigation == false), dataObject));

            ResourceInstanceKey key = new ResourceInstanceKey(container, resourceType, keyProperties.ToArray());
            KeyedResourceInstance keyResourceInstance = new KeyedResourceInstance(key, properties.ToArray());
            return keyResourceInstance;

        }
Esempio n. 9
0
        private void AddAssociation_Internal(KeyedResourceInstance parent, ResourceProperty property, KeyedResourceInstance child, bool addReverseLink)
        {
            bool changed;
            if (property.OtherAssociationEnd.Multiplicity == Multiplicity.Many)
                changed = AddEntityToCollection(child, FindRowInstance(parent), property.Name);
            else
                changed = UpdateLink(child, FindRowInstance(parent), property.Name);

            if (changed && addReverseLink && property.OtherSideNavigationProperty != null)
                AddAssociation_Internal(child, property.OtherSideNavigationProperty, parent, false);
        }
Esempio n. 10
0
 private void DataInserter_HandleAddingAssociation(KeyedResourceInstance parent, ResourceProperty property, KeyedResourceInstance child)
 {
     AddAssociation_Internal(parent, property, child, true);
 }
Esempio n. 11
0
 private void DataInserter_HandleAddingEntity(KeyExpression key, KeyedResourceInstance entity)
 {
     AddNewEntity(entity, key.ResourceType);
 }
Esempio n. 12
0
 private bool UpdateLink(KeyedResourceInstance updateTree, RowEntityType entityType, string linkProperty)
 {
     RowEntityType linkedEntity = FindRowInstance(updateTree);
     if (linkedEntity == null)
         throw new TestFailedException("Could not find row instance for updating link");
     entityType.Properties[linkProperty] = linkedEntity;
     return true;
 }
Esempio n. 13
0
        private bool AddEntityToCollection(KeyedResourceInstance updateTree, RowEntityType entityType, string linkProperty)
        {
            RowEntityType linkedEntity = FindRowInstance(updateTree);
            if (linkedEntity == null)
                throw new TestFailedException("Could not find row instance for adding entity to collection");

            //need to make sure its not already in the list
            List<RowEntityType> list = entityType.Properties[linkProperty] as List<RowEntityType>;
            if (list == null)
                entityType.Properties[linkProperty] = list = new List<RowEntityType>();

            foreach (RowEntityType e in list)
            {
                // if its actually the same reference, then the keys must match
                if (e == linkedEntity)
                    return false;

                // check the keys if its not the same reference
                bool match = true;
                foreach (ResourceInstanceSimpleProperty property in updateTree.KeyProperties)
                {
                    object value;
                    if (e.Properties.TryGetValue(property.Name, out value))
                    {
                        if (value != property.PropertyValue)
                        {
                            match = false;
                            break;
                        }
                    }
                }

                if (match)
                    return false;
            }

            list.Add(linkedEntity);
            return true;
        }
Esempio n. 14
0
        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;
        }
Esempio n. 15
0
 private RowEntityType FindRowInstance(KeyedResourceInstance updateTree)
 {
     return FindRowInstance(updateTree.ResourceSetName,
         updateTree.KeyProperties.OfType<ResourceInstanceSimpleProperty>().Select(p => p.Name).ToList(),
         updateTree.KeyProperties.OfType<ResourceInstanceSimpleProperty>().Select(p => p.PropertyValue).ToList());
 }
Esempio n. 16
0
        public static KeyedResourceInstance CreateKeyedResourceInstanceByClone(ResourceContainer container, ResourceType resourceType, bool excludeRelationships)
        {
            Workspace workspace = container.Workspace;
            //Clone for an existing resource, and update its key
            KeyExpression keyExpression = workspace.GetRandomExistingKey(container, resourceType);

            if (keyExpression == null)
                return null;

            KeyedResourceInstance dataObject = workspace.GetSingleResourceByKey(keyExpression);
            if (dataObject == null)
                return null;

            ResourceInstanceKey key = null;
            
            // if there are any non-server-generated key properties, then we need to build the key
            if (keyExpression.ResourceType.Properties.Any(p => p.PrimaryKey != null && !p.Facets.ServerGenerated))
            {
                ResourceType newResourceType = container.ResourceTypes.Where(rt => rt.Name == dataObject.TypeName).FirstOrDefault();
                key = CreateUniqueKey(container, newResourceType);
            }

            //Foreach property in dataObject create a ResourceProperty
            List<ResourceInstanceProperty> properties = new List<ResourceInstanceProperty>();
            properties.AddRange(dataObject.Properties.OfType<ResourceInstanceSimpleProperty>().ToArray());
            properties.AddRange(dataObject.Properties.OfType<ResourceInstanceComplexProperty>().ToArray());
            if (!excludeRelationships)
                properties.AddRange(CloneRequiredRelationships(container, keyExpression.ResourceType, keyExpression));

            KeyedResourceInstance keyResourceInstance = null;
            if (key != null)
                keyResourceInstance = new KeyedResourceInstance(key, properties.ToArray());
            else
                keyResourceInstance = new KeyedResourceInstance(dataObject.ResourceSetName, dataObject.TypeName, properties.ToArray());
            return keyResourceInstance;

        }
        private XmlElement CreateBasicEntryElement(KeyedResourceInstance keyedResourceInstance, XmlNode parentNode)
        {
            XmlElement entryElement = CreateAtomElement("entry");
            if (parentNode == null)
            {
                AddNamespacesToTopElement(entryElement);
                document.AppendChild(entryElement);
            }
            else
            {
                parentNode.AppendChild(entryElement);
            }

            //add type attribute
            if (keyedResourceInstance.IncludeTypeMetadataHint)
            {
                string typeName = null;

                //if( this.Workspace.DataLayerProviderKind == DataLayerProviderKind.NonClr )
                //    typeName = keyedResourceInstance.ResourceTypeName;
                //else
                typeName = this.Workspace.ContextNamespace + "." + keyedResourceInstance.TypeName;

                XmlElement typeElement = CreateAtomElement("category");
                typeElement.SetAttribute("scheme", DataWebSchemeNamespace);
                typeElement.SetAttribute("term", typeName);
                entryElement.AppendChild(typeElement);
            }

            return entryElement;
        }
        /// <summary>
        /// Implements IDataInserter.AddEntity by generating a IUpdatable.CreateResource call and multiple IUpdatable.SetValue calls
        /// </summary>
        /// <param name="key">Key expression for new entity</param>
        /// <param name="entity">Update tree for new entity</param>
        public void AddEntity(KeyExpression key, KeyedResourceInstance entity)
        {
            // generate a variable name for this entity and save it
            //
            int entityID = entityIDs.Count;
            entityIDs[entity] = entityID;
            string entityObjectName = "entity" + entityID;

            // code-gen the CreateResource and SetValue calls
            //
            code.AppendLine("//Adding entity");
            foreach(string line in WriteObject(entityObjectName, entity))
                code.AppendLine(line);
            code.AppendLine(entityListName + ".Add(" + entityObjectName + ");");
            code.AppendLine(string.Empty);

            // Fire the event
            //
            if (this.OnAddingEntity != null)
                OnAddingEntity(key, entity);

            // ensure that a later Flush/Close will write the SaveChanges call
            changesSaved = false;
        }
 private XmlElement CreateIdElement(KeyedResourceInstance keyedResourceInstance)
 {
     XmlElement idNode = CreateAtomElement("id");
     idNode.InnerText = CreateCanonicalUri(keyedResourceInstance.ResourceInstanceKey);
     return idNode;
 }
Esempio n. 20
0
            private ResourceBodyTree CanonicalResourcePayload(Workspace workspace, ResourceContainer resourceContainer)
            {
                ResourceType type = resourceContainer.BaseType;
                
                // TODO: support PUT by adding key support.

                ResourceInstanceProperty[] keyProperties = new ResourceInstanceProperty[0];
                ResourceInstanceKey keyExpression = new ResourceInstanceKey(resourceContainer,type, keyProperties);

                List<ResourceInstanceProperty> properties = new List<ResourceInstanceProperty>();
                foreach (NodeProperty p in type.Properties)
                {
                    // TODO: support to implement binding.
                    if (p.Type is ResourceCollection)
                    {
                        continue;
                    }
                    if (p.Type is ComplexType)
                    {
                        continue;
                    }

                    properties.Add(new ResourceInstanceSimpleProperty(p.Name, p.GetSampleValue()));
                }

                KeyedResourceInstance instance = new KeyedResourceInstance(keyExpression, properties.ToArray());
                return instance;
            }
Esempio n. 21
0
        public AstoriaRequest MakeMergeRequest(AstoriaRequest request, KeyedResourceInstance resourceInstance)
        {
            request.Verb = RequestVerb.Patch;
            request.ContentType = "application/atom+xml";
            request.UpdateTree = resourceInstance;

            return request;
        }