Esempio n. 1
0
            /// <summary>
            /// Visits a payload element whose root is an ServiceOperationDescriptor.
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(ServiceOperationDescriptor payloadElement)
            {
                ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

                var serviceOperationPayloadDescriptor = payloadElement as ServiceOperationDescriptor;

                ExceptionUtilities.CheckArgumentNotNull(serviceOperationPayloadDescriptor, "serviceOperationPayloadDescriptor");
                ExceptionUtilities.CheckObjectNotNull(serviceOperationPayloadDescriptor.Metadata, "serviceOperationPayloadDescriptor.Metadata cannot be null");

                this.writer.StartObjectScope();

                if (serviceOperationPayloadDescriptor.Title != null)
                {
                    this.writer.WriteName("title");
                    this.writer.WriteString(serviceOperationPayloadDescriptor.Title);
                }

                if (serviceOperationPayloadDescriptor.Target != null)
                {
                    this.writer.WriteName("target");
                    this.writer.WriteString(serviceOperationPayloadDescriptor.Target);
                }

                this.writer.EndScope();
            }
            /// <summary>
            /// Visits a payload element whose root is a ActionDescriptor.
            /// </summary>
            /// <param name="expected">The root node of payload element being visited.</param>
            public void Visit(ServiceOperationDescriptor expected)
            {
                ExceptionUtilities.CheckArgumentNotNull(expected, "expected");
                var observed = this.GetNextObservedElement <ServiceOperationDescriptor>();

                this.Assert.AreEqual(expected.Metadata, observed.Metadata, "Metadata did not match expectation");
                this.Assert.AreEqual(expected.Target, observed.Target, "Target did not match expectation");
                this.Assert.AreEqual(expected.Title, observed.Title, "Title did not match expectation");
            }
Esempio n. 3
0
            /// <summary>
            /// Visits a odata operation value.
            /// </summary>
            /// <param name="primitiveValue">The primitive value to visit.</param>
            protected override ODataPayloadElement VisitODataOperation(ODataOperation operation)
            {
                ServiceOperationDescriptor descriptor = new ServiceOperationDescriptor();

                descriptor.IsAction = true;
                if (operation is ODataFunction)
                {
                    descriptor.IsFunction = true;
                }

                descriptor.Metadata = operation.Metadata == null ? null : operation.Metadata.OriginalString;
                descriptor.Target   = operation.Target == null ? null : operation.Target.OriginalString;
                descriptor.Title    = operation.Title;

                return(descriptor);
            }
Esempio n. 4
0
        /// <summary>
        /// Visits the children of the given payload element and replaces it with a copy if any child changes
        /// </summary>
        /// <param name="serviceOperationDescriptor">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public virtual ODataPayloadElement Visit(ServiceOperationDescriptor serviceOperationDescriptor)
        {
            ExceptionUtilities.CheckArgumentNotNull(serviceOperationDescriptor, "serviceOperationDescriptor");

            if (this.alwaysReplace)
            {
                return(serviceOperationDescriptor.ReplaceWith <ServiceOperationDescriptor>(
                           new ServiceOperationDescriptor()
                {
                    IsAction = serviceOperationDescriptor.IsAction,
                    Metadata = serviceOperationDescriptor.Metadata,
                    Target = serviceOperationDescriptor.Target,
                    Title = serviceOperationDescriptor.Title
                }));
            }

            return(serviceOperationDescriptor);
        }
        private IEnumerable <ServiceOperationDescriptor> DeserializeServiceOperatonDescriptors(IEnumerable <XElement> serviceOperationPayloadElements)
        {
            List <ServiceOperationDescriptor> serviceOperationDescriptors = new List <ServiceOperationDescriptor>();

            foreach (var xelement in serviceOperationPayloadElements)
            {
                var serviceOperationDescriptor = new ServiceOperationDescriptor();

                if (xelement.Name == MetadataAction)
                {
                    serviceOperationDescriptor.IsAction = true;
                }

                serviceOperationDescriptor.Metadata = this.GetXAttributeValueIfExists(xelement.Attribute(XNameMetadata));
                serviceOperationDescriptor.Title    = this.GetXAttributeValueIfExists(xelement.Attribute(XNameTitle));
                serviceOperationDescriptor.Target   = this.GetXAttributeValueIfExists(xelement.Attribute(XNameTarget));
                serviceOperationDescriptors.Add(serviceOperationDescriptor);
            }

            return(serviceOperationDescriptors.AsEnumerable());
        }
        private void CreateServiceOperationDescriptor(XElement entryElement, ServiceOperationDescriptor serviceOperationPayloadAnnotation)
        {
            string elementName = "action";

            if (serviceOperationPayloadAnnotation.IsFunction)
            {
                elementName = "function";
            }

            XElement actionNode = CreateMetadataElement(entryElement, elementName);

            actionNode.Add(new XAttribute("metadata", serviceOperationPayloadAnnotation.Metadata));

            if (serviceOperationPayloadAnnotation.Title != null)
            {
                actionNode.Add(new XAttribute("title", serviceOperationPayloadAnnotation.Title));
            }

            if (serviceOperationPayloadAnnotation.Target != null)
            {
                actionNode.Add(new XAttribute("target", serviceOperationPayloadAnnotation.Target));
            }
        }
            /// <summary>
            /// Visits a payload element whose root is an ServiceOperationDescriptor.
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(ServiceOperationDescriptor payloadElement)
            {
                ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

                var serviceOperationPayloadDescriptor = payloadElement as ServiceOperationDescriptor;
                ExceptionUtilities.CheckArgumentNotNull(serviceOperationPayloadDescriptor, "serviceOperationPayloadDescriptor");
                ExceptionUtilities.CheckObjectNotNull(serviceOperationPayloadDescriptor.Metadata, "serviceOperationPayloadDescriptor.Metadata cannot be null");

                this.writer.StartObjectScope();

                if (serviceOperationPayloadDescriptor.Title != null)
                {
                    this.writer.WriteName("title");
                    this.writer.WriteString(serviceOperationPayloadDescriptor.Title);
                }

                if (serviceOperationPayloadDescriptor.Target != null)
                {
                    this.writer.WriteName("target");
                    this.writer.WriteString(serviceOperationPayloadDescriptor.Target);
                }

                this.writer.EndScope();
            }
        private void VerifyEntityOperations(ODataRequest request, ODataResponse response, List <EntityInstance> entities, bool isTopLevelElement)
        {
            foreach (var entity in entities.Where(et => !et.IsNull))
            {
                var instanceEntityType = this.model.EntityTypes.Single(et => et.FullName == entity.FullTypeName);

                // look at each action/function bound to the same type as entity, ensure it is advertised correctly
                int numberOfDescriptorsVerified = 0;
                var functionsWithBindings       = this.model.Functions.Where(f => f.Annotations.OfType <ServiceOperationAnnotation>().Any(s => s.BindingKind.IsBound())).ToArray();
                foreach (Function function in functionsWithBindings)
                {
                    ServiceOperationAnnotation serviceOperationAnnotation = function.Annotations.OfType <ServiceOperationAnnotation>().SingleOrDefault();
                    if (serviceOperationAnnotation != null)
                    {
                        DataType       bindingParameterDataType = function.Parameters[0].DataType;
                        EntityDataType bindingEntityDataType    = bindingParameterDataType as EntityDataType;
                        if (bindingEntityDataType == null)
                        {
                            ExceptionUtilities.Assert(bindingParameterDataType is CollectionDataType, "Unsupported binding parameter data type.");
                            ExceptionUtilities.Assert(entity.ServiceOperationDescriptors.SingleOrDefault(d => d.Title == function.Name) == null, "Unexpected feed-bound action advertised in entry.");
                            continue;
                        }

                        // Check the base type as well as derived types
                        bool beginServiceOpMatchMatching = bindingEntityDataType.Definition.Model.EntityTypes.Where(t => t.IsKindOf(bindingEntityDataType.Definition)).Where(a => a.FullName.Equals(entity.FullTypeName)).Any();

                        if (beginServiceOpMatchMatching)
                        {
                            // find ServiceOperationDescriptor that matches the function
                            ServiceOperationDescriptor descriptor = entity.ServiceOperationDescriptors.SingleOrDefault(d => ExtractSimpleActionName(d.Title) == function.Name);
                            bool expectActionDescriptor           = true;
                            if (request.Uri.SelectSegments.Count > 0)
                            {
                                expectActionDescriptor = this.ExpectActionWithProjection(request.Uri, function, isTopLevelElement);
                            }

                            if (descriptor == null)
                            {
                                ExceptionUtilities.Assert(!expectActionDescriptor, "Missing service operation descriptor for " + function.Name);
                            }
                            else
                            {
                                expectActionDescriptor = this.VerifyIfOpenType(function, bindingEntityDataType, expectActionDescriptor);

                                ExceptionUtilities.Assert(expectActionDescriptor, "Unexpected service operation descriptor for " + function.Name);

                                // JSONLight will always add the type segment if its a derived type now
                                string derivedTypeFullName = string.Empty;
                                var    acceptHeaderValue   = response.Headers[HttpHeaders.ContentType];
                                if (bindingEntityDataType.Definition.BaseType != null)
                                {
                                    derivedTypeFullName = string.Concat(bindingEntityDataType.Definition.FullName, "/");
                                }

                                if (bindingEntityDataType.Definition.FullName != instanceEntityType.FullName)
                                {
                                    derivedTypeFullName = string.Concat(instanceEntityType.FullName, "/");
                                }

                                // check if there is a possible name collision between a property and an action, if so add the Entity Container name to the expected result
                                string containerName = this.BuildExpectedContainerName(function, bindingEntityDataType, instanceEntityType);
                                string expectedMetadataContainerName = string.Concat(function.Model.GetDefaultEntityContainer().Name, ".");

                                // When running in JSONLight descriptor returns full name, not partial
                                if (IsJsonLightResponse(acceptHeaderValue))
                                {
                                    containerName = string.Concat(function.Model.GetDefaultEntityContainer().Name, ".");

                                    expectedMetadataContainerName = containerName;
                                }

                                string expectedTarget   = string.Concat(entity.Id.TrimEnd('/'), "/", derivedTypeFullName, containerName, function.Name);
                                string expectedMetadata = string.Concat(((ServiceRootSegment)request.Uri.RootSegment).Uri.AbsoluteUri.TrimEnd('/'), "/", Endpoints.Metadata, "#", expectedMetadataContainerName, function.Name);

                                this.Assert(descriptor.Target == expectedTarget, "Expected target " + expectedTarget + " Actual " + descriptor.Target, request, response);
                                this.Assert(descriptor.Metadata == expectedMetadata, "Expected Metadata " + expectedMetadata + " Actual " + descriptor.Metadata, request, response);

                                // verify IsAction flag
                                this.Assert(serviceOperationAnnotation.IsAction == descriptor.IsAction, "Expected action " + serviceOperationAnnotation.IsAction + " Actual " + descriptor.IsAction, request, response);
                                numberOfDescriptorsVerified++;
                            }
                        }
                    }
                }

                this.Assert(numberOfDescriptorsVerified == entity.ServiceOperationDescriptors.Count, "Wrong number of action/function.", request, response);
                this.VerifyExpandedEntityOperations(entity, request, response);
            }
        }
Esempio n. 9
0
        public void ReadActionsAndFunctionsTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            IEnumerable <ServiceOperationDescriptor> operations = new ServiceOperationDescriptor[]
            {
                new ServiceOperationDescriptor {
                    IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/Target"
                },
                new ServiceOperationDescriptor {
                    IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Title = "Title", Target = "http://odata.org/Target2"
                },
            };

            operations = operations.Concat(operations.Select(o => (ServiceOperationDescriptor) new ServiceOperationDescriptor {
                IsFunction = true, Metadata = o.Metadata, Title = o.Title, Target = o.Target
            }));

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = operations.Select(o =>
            {
                EntityInstance entityInstance = PayloadBuilder.Entity("TestModel.CityType");
                entityInstance.Add(o);
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = entityInstance,
                    PayloadEdmModel = model
                });
            });

            // Add couple more handcrafted cases
            testDescriptors.Concat(new PayloadReaderTestDescriptor[]
            {
                // Duplicate action - different targets
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action"
                    })
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action2"
                    }),
                    PayloadEdmModel = model
                },
                // Duplicate action - same targets
                // same targets in a metadata - allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action"
                    })
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action"
                    }),
                    PayloadEdmModel = model
                },
                // Duplicate function - different targets and titles
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1"
                    })
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function2", Title = "Function 2"
                    }),
                    PayloadEdmModel = model
                },
                // Duplicate function - same targets and titles
                // same targets in a metadata - allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1"
                    })
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1"
                    }),
                    PayloadEdmModel = model
                },
                // Function and Action with the same name (ODL doesn't validate this case)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/action", Title = "Action"
                    })
                                     .OperationDescriptor(new ServiceOperationDescriptor {
                        IsFunction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/function", Title = "Function"
                    }),
                    PayloadEdmModel = model
                },
            });

            // Generate interesting payloads for the EntityInstance with actions/functions
            // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                ODataVersionUtils.AllSupportedVersions,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom),
                (testDescriptor, maxProtocolVersion, testConfiguration) =>
            {
                if (maxProtocolVersion < testConfiguration.Version)
                {
                    // This would fail since the DSV > MPV.
                    return;
                }

                // In requests or if MPV < V3 we don't expect the operations to be read.
                if (testConfiguration.IsRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize);
                }

                testDescriptor.RunTest(testConfiguration.CloneAndApplyMaxProtocolVersion(maxProtocolVersion));
            });
        }
        private IEnumerable<ServiceOperationDescriptor> DeserializeServiceOperatonDescriptors(IEnumerable<XElement> serviceOperationPayloadElements)
        {
            List<ServiceOperationDescriptor> serviceOperationDescriptors = new List<ServiceOperationDescriptor>();
            foreach (var xelement in serviceOperationPayloadElements)
            {
                var serviceOperationDescriptor = new ServiceOperationDescriptor();

                if (xelement.Name == MetadataAction)
                {
                    serviceOperationDescriptor.IsAction = true;
                }

                serviceOperationDescriptor.Metadata = this.GetXAttributeValueIfExists(xelement.Attribute(XNameMetadata));
                serviceOperationDescriptor.Title = this.GetXAttributeValueIfExists(xelement.Attribute(XNameTitle));
                serviceOperationDescriptor.Target = this.GetXAttributeValueIfExists(xelement.Attribute(XNameTarget));
                serviceOperationDescriptors.Add(serviceOperationDescriptor);
            }

            return serviceOperationDescriptors.AsEnumerable();
        }
Esempio n. 11
0
 /// <summary>
 /// Visits the Service Operation Descriptor payload element
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public virtual void Visit(ServiceOperationDescriptor payloadElement)
 {
     ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
 }
 /// <summary>
 /// Visits a payload element whose root is a ServiceOperationDescriptor.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(ServiceOperationDescriptor payloadElement)
 {
     // TODO: queryvalues don't hold descriptor info, need to update
     ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
 }
Esempio n. 13
0
        public void ReadActionsAndFunctionsTest()
        {   
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            IEnumerable<ServiceOperationDescriptor> operations = new ServiceOperationDescriptor[]
            {
                new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/Target" },
                new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Title = "Title", Target = "http://odata.org/Target2" },
            };

            operations = operations.Concat(operations.Select(o => (ServiceOperationDescriptor)new ServiceOperationDescriptor { IsFunction = true, Metadata = o.Metadata, Title = o.Title, Target = o.Target }));

            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = operations.Select( o => 
                {
                    EntityInstance entityInstance = PayloadBuilder.Entity("TestModel.CityType");
                    entityInstance.Add(o);
                    return new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadElement = entityInstance,
                        PayloadEdmModel = model
                    };
                });

            // Add couple more handcrafted cases
            testDescriptors.Concat(new PayloadReaderTestDescriptor[]
            {
                // Duplicate action - different targets
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                        .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action2" }),
                    PayloadEdmModel = model
                },
                // Duplicate action - same targets
                // same targets in a metadata - allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                        .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" }),
                    PayloadEdmModel = model
                },
                // Duplicate function - different targets and titles
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                        .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" })
                        .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function2", Title = "Function 2" }),
                    PayloadEdmModel = model
                },
                // Duplicate function - same targets and titles
                // same targets in a metadata - allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                        .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" })
                        .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" }),
                    PayloadEdmModel = model
                },
                // Function and Action with the same name (ODL doesn't validate this case)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                        .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/action", Title = "Action" })
                        .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/function", Title = "Function" }),
                    PayloadEdmModel = model
                },
            });

            // Generate interesting payloads for the EntityInstance with actions/functions
            // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                ODataVersionUtils.AllSupportedVersions,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom),
                (testDescriptor, maxProtocolVersion, testConfiguration) =>
                {
                    if (maxProtocolVersion < testConfiguration.Version)
                    {
                        // This would fail since the DSV > MPV.
                        return;
                    }

                    // In requests or if MPV < V3 we don't expect the operations to be read.
                    if (testConfiguration.IsRequest)
                    {
                        testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                        testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize);
                    }

                    testDescriptor.RunTest(testConfiguration.CloneAndApplyMaxProtocolVersion(maxProtocolVersion));
                });
        }