예제 #1
0
        /// <summary>Registers a data type with the data service runtime so that it can be used by a custom data service provider.</summary>
        /// <param name="typeName">The namespace-qualified name of the type that is enabled for use with the custom data service provider.</param>
        /// <remarks>
        /// This method is used to register a type with the Astoria runtime which may be returned in the �open properties� of
        /// an open type such that the type is visible in $metadata output and usable with CRUD operations.
        ///
        /// The typename parameter must be a namespace qualified type name (format: &lt;namespace&gt;.&lt;typename&gt;).
        /// The name provided must be as it would show up in a CSDL document (ie. model types, not CLR types)
        ///
        /// The types registered via calls to EnableAccess will be additive to those implicitly made accessible via
        /// DSC.SetEntitySetAccessRule(�) invocations
        ///  � Note: The Astoria runtime layer won�t be able to determine if a typename specified maps to an Entity Type,
        ///    Complex Type, etc until it actually obtains type info (entity types, complex types, etc) from the underlying provider
        ///  � �*� can be used as the value of �typename�, which will be interpreted as matching all types
        ///
        /// When Astoria enumerates types or needs to obtain a type (Complex Types, Entity Types) from the underlying provider
        /// it will first determine if the type should be visible (show in $metadata and accessible via operations exposed by the
        /// service) as per the standard v1 checks (ie. driven by SetEntitySetAccessRule calls). If the type is not visible via V1
        /// rules, then we consult the set of types registered via EnableAccess(&lt;typename&gt;) invocations.  If the type was
        /// included in such a call then the type is visible via $metadata and can be accessed via CRUD ops, etc.
        ///
        /// If a type is not made visible via one of the mechanisms above, then:
        ///   � That type must not be included a response to a $metadata request
        ///   � Instances of the type must not be returned to the client as the response of a request to the data service.
        ///     If such a type instance would be required the service MUST fail the request.  Failure semantics are covered
        ///     in the area of the specification which covers request/response semantics with respect to open types.
        ///
        /// Invoking this method multiple times with the same type name is allowed and considered a �NO OP�.
        /// </remarks>
        public void EnableTypeAccess(string typeName)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(typeName, "typeName");
            this.CheckNotSealed();

            if (typeName == "*")
            {
                this.accessEnabledForAllResourceTypes = true;
            }
            else
            {
                ResourceType resourceType;
                if (!this.provider.TryResolveResourceType(typeName, out resourceType) || resourceType == null)
                {
                    throw new ArgumentException(Strings.DataServiceConfiguration_ResourceTypeNameNotFound(typeName), "typeName");
                }

                if (resourceType.ResourceTypeKind != ResourceTypeKind.ComplexType)
                {
                    throw new ArgumentException(Strings.DataServiceConfiguration_NotComplexType(typeName), "typeName");
                }

                Debug.Assert(resourceType.FullName == typeName, "resourceType.FullName == typeName");
                this.accessEnabledResourceTypes.Add(typeName);
            }
        }
        /// <summary>
        /// Initializes a new instance of <see cref="ServiceActionResolverArgs"/>.
        /// </summary>
        /// <param name="serviceActionName"> The service action name taken from the URI.</param>
        /// <param name="bindingType">The binding type based on interpreting the URI preceeding the action, or null if the action is being invoked from the root of the service.</param>
        public ServiceActionResolverArgs(string serviceActionName, ResourceType bindingType)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(serviceActionName, "serviceActionName");
            this.ServiceActionName = serviceActionName;

            // binding type is explicitly allowed to be null.
            this.BindingType = bindingType;
        }
예제 #3
0
 public ResourceProperty(string name, ResourcePropertyKind kind, System.Data.Services.Providers.ResourceType propertyResourceType)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckArgumentNull <System.Data.Services.Providers.ResourceType>(propertyResourceType, "propertyResourceType");
     ValidatePropertyParameters(kind, propertyResourceType);
     this.kind = kind;
     this.name = name;
     this.propertyResourceType             = propertyResourceType;
     this.canReflectOnInstanceTypeProperty = !kind.HasFlag(ResourcePropertyKind.Stream);
 }
        public IEdmEntitySet FindEntitySet(string name)
        {
            IEdmEntitySet set;

            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            if (!this.entitySetCache.TryGetValue(name, out set))
            {
                return(null);
            }
            return(set);
        }
예제 #5
0
 protected internal OperationParameter(string name, ResourceType parameterType)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckArgumentNull <ResourceType>(parameterType, "parameterType");
     if ((parameterType.ResourceTypeKind == ResourceTypeKind.Primitive) && (parameterType == ResourceType.GetPrimitiveResourceType(typeof(Stream))))
     {
         throw new ArgumentException(Strings.ServiceOperationParameter_TypeNotSupported(name, parameterType.FullName), "parameterType");
     }
     this.name = name;
     this.type = parameterType;
 }
        public IEnumerable <IEdmFunctionImport> FindFunctionImports(string name)
        {
            List <MetadataProviderEdmFunctionImport> list;

            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            if (!this.functionImportCache.TryGetValue(name, out list))
            {
                return(Enumerable.Empty <IEdmFunctionImport>());
            }
            return((IEnumerable <IEdmFunctionImport>)list.AsReadOnly());
        }
예제 #7
0
 public ResourceSet(string name, System.Data.Services.Providers.ResourceType elementType)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckArgumentNull <System.Data.Services.Providers.ResourceType>(elementType, "elementType");
     if (elementType.ResourceTypeKind != ResourceTypeKind.EntityType)
     {
         throw new ArgumentException(System.Data.Services.Strings.ResourceContainer_ContainerMustBeAssociatedWithEntityType);
     }
     this.name          = name;
     this.elementType   = elementType;
     this.queryRootType = typeof(IQueryable <>).MakeGenericType(new Type[] { elementType.InstanceType });
 }
예제 #8
0
 public bool TryResolveResourceType(string name, out ResourceType resourceType)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     foreach (ResourceType type in this.TypeCache.Values)
     {
         if (type.FullName == name)
         {
             resourceType = type;
             return(true);
         }
     }
     resourceType = null;
     return(false);
 }
        /// <summary>
        /// Searches for an entity set with the given name in this entity container and returns null if no such set exists.
        /// </summary>
        /// <param name="name">The name of the element being found.</param>
        /// <returns>The requested entity set, or null if the entity set does not exist.</returns>
        /// <remarks>
        /// Cache state: EntityContainers required. We only support looking up entity sets once
        ///     all entity containers have been completely populated and cached.
        /// </remarks>
        public IEdmEntitySet FindEntitySet(string name)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");

            // NOTE: for the query parser we might want to allow incremental lookup
            //       of entity sets in the future.
            IEdmEntitySet entitySet;

            if (this.entitySetCache.TryGetValue(name, out entitySet))
            {
                return(entitySet);
            }

            return(this.LazyLoadEntitySet(name));
        }
        /// <summary>
        /// Searches for operation imports with the given name in this entity container and returns an empty enumerable
        /// if no such operation import exists.
        /// </summary>
        /// <param name="operationName">The name of the operation import being found.</param>
        /// <returns>A group of the requested operation imports, or an empty enumerable if no such operation import exists.</returns>
        /// <remarks>
        /// Cache state: EntityContainers required. We only support looking up an operation imports once
        ///     all entity containers have been completely populated and cached.
        /// </remarks>
        public IEnumerable <IEdmOperationImport> FindOperationImports(string operationName)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(operationName, "operationName");

            List <IEdmOperationImport> operationImports;

            // NOTE: for the query parser we might want to allow incremental lookup
            //       of operation imports in the future.
            if (this.operationImportCache.TryGetValue(operationName, out operationImports))
            {
                return(operationImports.AsReadOnly());
            }

            return(this.LazyLoadServiceOperationImports(operationName));
        }
예제 #11
0
        /// <summary>Initializes a new <see cref="T:Microsoft.OData.Service.Providers.ResourceProperty" /> for an open property.</summary>
        /// <param name="name">Property name for the property as string.</param>
        /// <param name="kind">
        ///   <see cref="T:Microsoft.OData.Service.Providers.ResourcePropertyKind" />.</param>
        /// <param name="propertyResourceType">The <see cref="T:Microsoft.OData.Service.Providers.ResourceType" /> of the resource to which the property refers.</param>
        public ResourceProperty(
            string name,
            ResourcePropertyKind kind,
            ResourceType propertyResourceType)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            WebUtil.CheckArgumentNull(propertyResourceType, "propertyResourceType");

            ValidatePropertyParameters(kind, propertyResourceType);

            this.kind = kind;
            this.name = name;
            this.propertyResourceType             = propertyResourceType;
            this.canReflectOnInstanceTypeProperty = kind.HasFlag(ResourcePropertyKind.Stream) ? false : true;
        }
예제 #12
0
        /// <summary>Given the specified name, tries to find a type.</summary>
        /// <param name="name">Name of the type to resolve.</param>
        /// <param name="resourceType">Returns the resolved resource type, null if no resource type for the given name was found.</param>
        /// <returns>True if we found the resource type for the given name, false otherwise.</returns>
        public virtual bool TryResolveResourceType(string name, out ResourceType resourceType)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            Debug.Assert(this.metadata != null, "this.metadata != null");
            foreach (var cacheItem in this.metadata.ResourceTypeCacheItems)
            {
                if (cacheItem.ResourceType.FullName == name)
                {
                    resourceType = cacheItem.ResourceType;
                    return(true);
                }
            }

            resourceType = null;
            return(false);
        }
예제 #13
0
 public ResourceAssociationSet(string name, ResourceAssociationSetEnd end1, ResourceAssociationSetEnd end2)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckArgumentNull <ResourceAssociationSetEnd>(end1, "end1");
     WebUtil.CheckArgumentNull <ResourceAssociationSetEnd>(end2, "end2");
     if ((end1.ResourceProperty == null) && (end2.ResourceProperty == null))
     {
         throw new ArgumentException(Strings.ResourceAssociationSet_ResourcePropertyCannotBeBothNull);
     }
     if ((end1.ResourceType == end2.ResourceType) && (end1.ResourceProperty == end2.ResourceProperty))
     {
         throw new ArgumentException(Strings.ResourceAssociationSet_SelfReferencingAssociationCannotBeBiDirectional);
     }
     this.name = name;
     this.end1 = end1;
     this.end2 = end2;
 }
예제 #14
0
 /// <summary>Sets the permissions for the specified service action.</summary>
 /// <param name="name">The name of the service action for which to set permissions.</param>
 /// <param name="rights">The access rights to be granted to this action, passed as a <see cref="T:Microsoft.OData.Service.ServiceActionRights" /> value.</param>
 public void SetServiceActionAccessRule(string name, ServiceActionRights rights)
 {
     this.CheckNotSealed();
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckServiceActionRights(rights, "rights");
     if (name == "*")
     {
         this.rightsForUnspecifiedServiceAction = rights;
     }
     else
     {
         // We initialize the service configuration before the action provider can be
         // loaded. We will not validate the service action names to make sure they
         // actually exist in the action provider.
         this.serviceActionRights[name] = rights;
     }
 }
예제 #15
0
 public ResourceType(Type instanceType, System.Data.Services.Providers.ResourceTypeKind resourceTypeKind, ResourceType baseType, string namespaceName, string name, bool isAbstract) : this(instanceType, baseType, namespaceName, name, isAbstract)
 {
     WebUtil.CheckArgumentNull <Type>(instanceType, "instanceType");
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckResourceTypeKind(resourceTypeKind, "resourceTypeKind");
     if (((resourceTypeKind == System.Data.Services.Providers.ResourceTypeKind.Primitive) || (resourceTypeKind == System.Data.Services.Providers.ResourceTypeKind.Collection)) || (resourceTypeKind == System.Data.Services.Providers.ResourceTypeKind.EntityCollection))
     {
         throw new ArgumentException(System.Data.Services.Strings.ResourceType_InvalidValueForResourceTypeKind("resourceTypeKind"), "resourceTypeKind");
     }
     if ((baseType != null) && (baseType.ResourceTypeKind != resourceTypeKind))
     {
         throw new ArgumentException(System.Data.Services.Strings.ResourceType_InvalidResourceTypeKindInheritance(resourceTypeKind.ToString(), baseType.ResourceTypeKind.ToString()), "resourceTypeKind");
     }
     if (instanceType.IsValueType)
     {
         throw new ArgumentException(System.Data.Services.Strings.ResourceType_TypeCannotBeValueType, "instanceType");
     }
     this.resourceTypeKind = resourceTypeKind;
 }
예제 #16
0
        public IEdmSchemaType FindDeclaredType(string qualifiedName)
        {
            IEdmSchemaType type;

            WebUtil.CheckStringArgumentNullOrEmpty(qualifiedName, "qualifiedName");
            if (this.schemaTypeCache.TryGetValue(qualifiedName, out type))
            {
                return(type);
            }
            if (this.coreModel.FindDeclaredType(qualifiedName) == null)
            {
                if (this.cacheState == MetadataProviderState.Full)
                {
                    return(null);
                }
                ResourceType resourceType = this.metadataProvider.TryResolveResourceType(qualifiedName);
                if (resourceType != null)
                {
                    return(this.EnsureSchemaType(resourceType));
                }
            }
            return(null);
        }
예제 #17
0
 internal Operation(string name, ServiceOperationResultKind resultKind, ResourceType returnType, System.Data.Services.Providers.ResourceSet resultSet, ResourceSetPathExpression resultSetPathExpression, string method, IEnumerable <OperationParameter> parameters, System.Data.Services.Providers.OperationParameterBindingKind operationParameterBindingKind, OperationKind kind)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     WebUtil.CheckServiceOperationResultKind(resultKind, "resultKind");
     WebUtil.CheckStringArgumentNullOrEmpty(method, "method");
     ValidateConstructorArguments(name, returnType, resultSet, resultSetPathExpression, method, operationParameterBindingKind, kind);
     this.name                          = name;
     this.resultKind                    = resultKind;
     this.returnType                    = returnType;
     this.resourceSet                   = resultSet;
     this.resultSetPathExpression       = resultSetPathExpression;
     this.method                        = method;
     this.kind                          = kind;
     this.operationParameterBindingKind = operationParameterBindingKind;
     this.operationParameters           = ValidateParameters(this.operationParameterBindingKind, parameters);
     if (this.operationParameterBindingKind != System.Data.Services.Providers.OperationParameterBindingKind.Never)
     {
         this.bindingParameter = this.operationParameters.FirstOrDefault <OperationParameter>();
         if (this.bindingParameter == null)
         {
             throw new ArgumentException(System.Data.Services.Strings.ServiceOperation_BindableOperationMustHaveAtLeastOneParameter, "operationParameterBindingKind");
         }
         if (((resultSetPathExpression != null) && (this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType)) && (this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection))
         {
             throw new ArgumentException(System.Data.Services.Strings.ServiceOperation_BindingParameterMustBeEntityToUsePathExpression("resultSetPathExpression"));
         }
         if (((this.kind == OperationKind.Action) && (this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType)) && (this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection))
         {
             throw new ArgumentException(System.Data.Services.Strings.ServiceOperation_ActionBindingMustBeEntityOrEntityCollection, "parameters");
         }
         if (this.resultSetPathExpression != null)
         {
             this.resultSetPathExpression.SetBindingParameter(this.bindingParameter);
         }
     }
 }
예제 #18
0
        /// <summary>
        /// Initializes a new <see cref="Operation"/> instance.
        /// </summary>
        /// <param name="name">name of the operation.</param>
        /// <param name="resultKind">Kind of result expected from this operation.</param>
        /// <param name="returnType">Return type of the operation.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation, must be null if <paramref name="resultSetPathExpression"/> is not null.</param>
        /// <param name="resultSetPathExpression">Path expression to calculate the result set of the operation, must be null if <paramref name="resultSet"/> is not null.</param>
        /// <param name="method">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <param name="parameters">In-order parameters for this operation.</param>
        /// <param name="operationParameterBindingKind">the kind of the operation parameter binding (Never, Sometimes, Always).</param>
        /// <param name="kind">The kind of the current service operation.</param>
        internal Operation(
            string name,
            ServiceOperationResultKind resultKind,
            ResourceType returnType,
            ResourceSet resultSet,
            ResourceSetPathExpression resultSetPathExpression,
            string method,
            IEnumerable <OperationParameter> parameters,
            OperationParameterBindingKind operationParameterBindingKind,
            OperationKind kind)
        {
            WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
            WebUtil.CheckServiceOperationResultKind(resultKind, "resultKind");
            WebUtil.CheckStringArgumentNullOrEmpty(method, "method");

            Debug.Assert(
                this.GetType() == typeof(ServiceOperation) && kind == OperationKind.ServiceOperation ||
                this.GetType() == typeof(ServiceAction) && kind == OperationKind.Action,
                "OperationKind and the current type doesn't match.");

            ValidateConstructorArguments(name, returnType, resultSet, resultSetPathExpression, method, operationParameterBindingKind, kind);
            this.name                          = name;
            this.resultKind                    = resultKind;
            this.returnType                    = returnType;
            this.resourceSet                   = resultSet;
            this.resultSetPathExpression       = resultSetPathExpression;
            this.method                        = method;
            this.kind                          = kind;
            this.operationParameterBindingKind = operationParameterBindingKind;
            this.operationParameters           = Operation.ValidateParameters(this.operationParameterBindingKind, parameters);

            if (this.operationParameterBindingKind != OperationParameterBindingKind.Never)
            {
                Debug.Assert(
                    this.operationParameterBindingKind == OperationParameterBindingKind.Always || this.operationParameterBindingKind == OperationParameterBindingKind.Sometimes,
                    "Value of operationParameterBindingKind was expected to be 'always' or 'sometimes'.");

                Debug.Assert(this.kind != OperationKind.ServiceOperation, "ServiceOperations should never be bindable.");
                this.bindingParameter = this.operationParameters.FirstOrDefault();
                if (this.bindingParameter == null)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindableOperationMustHaveAtLeastOneParameter, "operationParameterBindingKind");
                }

                if (resourceSet != null)
                {
                    throw new ArgumentException(Strings.Opereration_BoundOperationsMustNotSpecifyEntitySetOnlyEntitySetPath(this.name), "resourceSet");
                }

                if (resultSetPathExpression != null &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType &&
                    this.bindingParameter.ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    throw new ArgumentException(Strings.ServiceOperation_BindingParameterMustBeEntityToUsePathExpression("resultSetPathExpression"));
                }

                if (this.kind == OperationKind.Action &&
                    !(this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType ||
                      this.bindingParameter.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    throw new ArgumentException(Strings.ServiceOperation_ActionBindingMustBeEntityOrEntityCollection, "parameters");
                }

                if (this.resultSetPathExpression != null)
                {
                    this.resultSetPathExpression.SetBindingParameter(this.bindingParameter);
                }
            }

            Debug.Assert(this.kind != OperationKind.Action || string.CompareOrdinal(XmlConstants.HttpMethodPost, this.method) == 0, "HttpMethod must be POST for Actions.");
            Debug.Assert(this.resourceSet == null || this.resultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
        }
예제 #19
0
 public bool TryResolveResourceSet(string name, out ResourceSet resourceSet)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     return(this.EntitySets.TryGetValue(name, out resourceSet));
 }
예제 #20
0
 public bool TryResolveServiceOperation(string name, out ServiceOperation serviceOperation)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     return(this.metadata.ServiceOperations.TryGetValue(name, out serviceOperation));
 }
예제 #21
0
 public IEdmEntityContainer FindDeclaredEntityContainer(string name)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(name, "name");
     this.RunInState(new Action(this.EnsureEntityContainers), MetadataProviderState.EntityContainers);
     return(this.FindExistingEntityContainer(name));
 }
예제 #22
0
 /// <summary> Creates a new instance of the <see cref="T:Microsoft.OData.Service.Providers.ResourceSetPathExpression" /> class. </summary>
 /// <param name="pathExpression">Path expression to calculate the target resource set of a function or procedure.</param>
 /// <remarks>The <paramref name="pathExpression"/> must start with the binding parameter name followed by navigation properties that are separated by "/".
 /// For example, if the binding parameter is customer, a valid path can be "customer/Orders/OrderDetails".</remarks>
 public ResourceSetPathExpression(string pathExpression)
 {
     WebUtil.CheckStringArgumentNullOrEmpty(pathExpression, "pathExpression");
     this.pathExpression = pathExpression;
 }