/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string url = svcStatus.RootURL + "?$format=application/json"; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionFormat", url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { passed = resp.ResponsePayload.IsJsonLightSvcDoc(); } else { passed = false; } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; //var svcStatus = ServiceStatus.GetInstance(); var svcStatus = ServiceStatus.GetInstance(context.ServiceBaseUri.OriginalString, context.ResponseHttpHeaders.Replace("\r\n", ";")); string url = svcStatus.RootURL.TrimEnd('/') + @"/$metadata"; var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (!string.IsNullOrEmpty(context.MetadataDocument)) { passed = true; } else { passed = false; } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propTypes = new string[2] { "Edm.Date", "Edm.DateTimeOffset" }; var propNames = MetadataHelper.GetPropertyNames(propTypes, out entityTypeShortName); if (null == propNames || !propNames.Any()) { return(passed); } string propName = propNames[0]; var entitySetUrl = entityTypeShortName.GetAccessEntitySetURL(); if (string.IsNullOrEmpty(entitySetUrl)) { return(passed); } string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { JObject jObj = JObject.Parse(resp.ResponsePayload); JArray jArr = jObj.GetValue(Constants.Value) as JArray; var entity = jArr.First as JObject; var propVal = Convert.ToDateTime(entity[propName]).Minute; url = string.Format("{0}?$filter=minute({1}) eq {2}", url, propName, propVal); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { jObj = JObject.Parse(resp.ResponsePayload); jArr = jObj.GetValue(Constants.Value) as JArray; foreach (JObject et in jArr) { passed = Convert.ToDateTime(et[propName]).Minute == propVal; } } else { passed = false; } } return(passed); }
/// <summary> /// Verify whether an entity-set URL is existent in the service. /// </summary> /// <param name="entitySetURL">An entity-set URL.</param> /// <returns>Returns true if exist, otherwise false.</returns> public static bool IsSpecifiedEntitySetURLExist(this string entitySetURL) { if (string.IsNullOrEmpty(entitySetURL)) { return(false); } JObject serviceRoot = JObject.Parse(ServiceStatus.GetInstance().ServiceDocument); var entries = JsonParserHelper.GetEntries(serviceRoot); if (null == entries || !entries.Any()) { return(false); } var entry = entries .Where(e => "EntitySet" == e["kind"].Value <string>() && entitySetURL == e["url"].Value <string>()) .Select(e => e); try { return(null != entry && entry.Any()); } catch { return(false); } }
/// <summary> /// Add namespace prefix for any names of the element in metadata document. /// </summary> /// <param name="targetName">The target element's name.</param> /// <param name="appliesType">The applies type of the element. (Related to the element's local-name.)</param> /// <param name="metadataDoc">The metadata document.</param> /// <returns>Returns the name with the namespace of the element.</returns> public static string AddNamespace(this string targetName, AppliesToType appliesType) { if (string.IsNullOrEmpty(targetName)) { return(string.Empty); } string target = targetName.GetLastSegment(); XElement metadata = XElement.Parse(ServiceStatus.GetInstance().MetadataDocument); string xpath = string.Format(@"//*[local-name()='{0}' and @Name='{1}']", appliesType, target); var element = metadata.XPathSelectElement(xpath, ODataNamespaceManager.Instance); if (null == element) { return(string.Empty); } AliasNamespacePair aliasNamespace = element.GetAliasAndNamespace(); if (string.IsNullOrEmpty(aliasNamespace.Namespace)) { return(string.Empty); } return(string.Format("{0}.{1}", aliasNamespace.Namespace, target)); }
/// <summary> /// Gets the amount of entities from a feed. /// </summary> /// <param name="entitySetUrl">A feed URL.</param> /// <returns>Return the amount of entities in current feed.</returns> public static int GetEntitiesCountFromFeed(string entitySetUrl, IEnumerable <KeyValuePair <string, string> > headers = null) { int amount = 0; if (!Uri.IsWellFormedUriString(entitySetUrl, UriKind.Absolute)) { throw new UriFormatException("The input parameter 'entitySetUrl' is not a URL string."); } var resp = WebHelper.Get(new Uri(entitySetUrl), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, headers); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue(Constants.Value) as JArray; amount += jArr.Count; while (null != jObj[Constants.V4OdataNextLink]) { string url = Uri.IsWellFormedUriString(jObj[Constants.V4OdataNextLink].ToString(), UriKind.Absolute) ? jObj[Constants.V4OdataNextLink].ToString() : ServiceStatus.GetInstance().RootURL.TrimEnd('/') + "/" + jObj[Constants.V4OdataNextLink].ToString(); resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, headers); jObj = JObject.Parse(resp.ResponsePayload); jArr = jObj.GetValue(Constants.Value) as JArray; amount += jArr.Count; //if (amount > 1000) //{ // break; //} } } return(amount); }
/// <summary> /// Get accessable key properties from entity-type. /// </summary> /// <param name="entitySetUrl">The entity-set URL.</param> /// <returns>Returns the accessable key properties.</returns> private static List <Tuple <string, string> > GetAccessKeyProperties(this string entitySetUrl) { if (string.IsNullOrEmpty(entitySetUrl)) { throw new ArgumentNullException(string.Format(ParamNullErrorMsgPattern, "entitySetUrl")); } var result = new List <Tuple <string, string> >(); var svcStatus = ServiceStatus.GetInstance(); var metadata = XElement.Parse(svcStatus.MetadataDocument); if (entitySetUrl.IsSpecifiedEntitySetURLExist()) { var entityTypeShortName = entitySetUrl.MapEntitySetURLToEntityTypeShortName(); if (!string.IsNullOrEmpty(entityTypeShortName)) { return(entityTypeShortName.GetAccessKeyPropertiesET()); } } string xPath = string.Format("//*[local-name()='NavigationProperty' and @Name='{0}' and @ContainsTarget='true']", entitySetUrl); var navigPropElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (null != navigPropElem && null != navigPropElem.Attribute("Type")) { string navigPropType = navigPropElem.GetAttributeValue("Type"); var etShortName = navigPropType.RemoveCollectionFlag().GetLastSegment(); return(etShortName.GetAccessKeyPropertiesET()); } return(null); }
/// <summary> /// Provide the value tempalte of a collection. /// </summary> /// <param name="type">The name of the collection content type.</param> /// <returns>The JSON array of the collection.</returns> public JArray ConstructCollectionTypeValue(string type) { string metadataDoc = ServiceStatus.GetInstance().MetadataDocument; JArray array = new JArray(); List <string> complextTypeNames = MetadataHelper.GetAllComplexNameFromMetadata(metadataDoc); if (EdmTypeManager.IsEdmSimpleType(type)) { string value = ConstructPrimitiveTypeValue(type); array.Add(value); array.Add(value); } else if (complextTypeNames != null && complextTypeNames.Count > 0 && complextTypeNames.Contains(type)) { JObject objValue = ConstructAComplexTypeValue(type); array.Add(objValue); array.Add(objValue); } else if (MetadataHelper.IsEnumType(metadataDoc, type)) { array.Add(ConstructEnumTypeValue(type)); array.Add(ConstructEnumTypeValue(type)); } return(array); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); var entitySetUrls = MetadataHelper.GetEntitySetURLs(); var entitySetUrl = entitySetUrls[0]; string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; int actualNum = JsonParserHelper.GetEntitiesCountFromFeed(url, svcStatus.DefaultHeaders); url = string.Format("{0}?$skip={1}", url, actualNum - 1); var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionSkip", url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { JObject jObj = JObject.Parse(resp.ResponsePayload); JArray jArr = jObj.GetValue("value") as JArray; passed = 1 == jArr.Count; } else { passed = false; } return(passed); }
/// <summary> /// Construct a complex type value according to its metadata definition. /// </summary> /// <param name="complexName">The name of the complex type.</param> /// <returns>The JSON object value of the complex type.</returns> public JObject ConstructAComplexTypeValue(string complexName) { string metadataDoc = ServiceStatus.GetInstance().MetadataDocument; JObject result = new JObject(); List <string> complextTypeNames = MetadataHelper.GetAllComplexNameFromMetadata(metadataDoc); Dictionary <string, string> properties = MetadataHelper.GetAllPropertiesOfComplexType(metadataDoc, complexName); foreach (string prop in properties.Keys) { string type = properties[prop]; if (EdmTypeManager.IsEdmSimpleType(type)) { IEdmType edmType = EdmTypeManager.GetEdmType(type); result[prop] = edmType.GetJsonValueTemplate(); } else if (type.Contains("Collection")) { string itemType = type.Substring(type.IndexOf('(') + 1, type.Length - 12).GetLastSegment(); result[prop] = ConstructCollectionTypeValue(itemType); } else if (MetadataHelper.IsEnumType(metadataDoc, type)) { result[prop] = ConstructEnumTypeValue(type); } else if (complextTypeNames != null && complextTypeNames.Contains(type)) { result[prop] = ConstructAComplexTypeValue(type); } } return(result); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string url = svcStatus.RootURL.TrimEnd('/'); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (!string.IsNullOrEmpty(context.ServiceDocument)) { passed = true; } else { passed = false; } return(passed); }
/// <summary> /// Map entity-set URL to entity-set name. /// </summary> /// <param name="entitySetURL">An entity-set URL.</param> /// <returns>Returns the related entity-set name.</returns> public static string MapEntitySetURLToEntitySetName(this string entitySetURL) { if (string.IsNullOrEmpty(entitySetURL)) { throw new ArgumentNullException(string.Format(ParamNullErrorMsgPattern, "entitySetURL")); } if (!IsSpecifiedEntitySetURLExist(entitySetURL)) { throw new ArgumentException(string.Format(ParamNotFoundErrorMsgPattern, "entity-set", "URL", "entitySetURL")); } JObject serviceRoot = JObject.Parse(ServiceStatus.GetInstance().ServiceDocument); var entries = JsonParserHelper.GetEntries(serviceRoot); if (null != entries) { foreach (var entry in entries) { if (null != entry["url"] && entitySetURL == entry["url"].Value <string>() && null != entry["kind"] && "EntitySet" == entry["kind"].Value <string>()) { return(null != entry["name"] ? entry["name"].Value <string>() : string.Empty); } } } return(string.Empty); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var keyProp = MetadataHelper.GetKeyProperty(out entityTypeShortName); if (null == keyProp) { return(passed); } string keyPropName = keyProp.Item1; string keyPropType = keyProp.Item2; if (string.IsNullOrEmpty(entityTypeShortName) || string.IsNullOrEmpty(keyPropName) || string.IsNullOrEmpty(keyPropType)) { return(passed); } string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue("value") as JArray; var temp = ((JObject)(jArr.First))[keyPropName]; if (null == temp) { return(passed); } var keyPropVal = temp.ToString(); string pattern = "Edm.String" == keyPropType ? "{0}('{1}')/{2}/$value" : "{0}({1})/{2}/$value"; url = string.Format(pattern, url, keyPropVal, keyPropName); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionValue", url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { passed = resp.ResponsePayload == keyPropVal; } else { passed = false; } } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propNames = MetadataHelper.GetPropertyNames( "Edm.String", out entityTypeShortName, 2, (elem) => { return(!(null != elem.Attribute("MaxLength") && elem.GetAttributeValue("MaxLength") == "max")); }); if (null == propNames || propNames.Count < 2) { return(passed); } string propName1 = propNames[0]; string propName2 = propNames[1]; var entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { JObject jObj = JObject.Parse(resp.ResponsePayload); JArray jArr = jObj.GetValue(Constants.Value) as JArray; var entity = jArr.First as JObject; var propVal1 = entity[propName1].ToString(); var propVal2 = entity[propName2].ToString(); url = string.Format("{0}?$filter=concat(concat({1}, ': '), {2}) eq '{3}: {4}'", url, propName1, propName2, propVal1, propVal2); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { jObj = JObject.Parse(resp.ResponsePayload); jArr = jObj.GetValue(Constants.Value) as JArray; foreach (JObject et in jArr) { passed = string.Format("{0}: {1}", et[propName1].ToString(), et[propName2].ToString()) == string.Format("{0}: {1}", propVal1, propVal2); } } else { passed = false; } } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propNames = MetadataHelper.GetPropertyNames("Edm.String", out entityTypeShortName); if (null == propNames || !propNames.Any()) { return(passed); } string propName = propNames[0]; var entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { JObject jObj = JObject.Parse(resp.ResponsePayload); JArray jArr = jObj.GetValue(Constants.Value) as JArray; var entity = jArr.First as JObject; var propVal = entity[propName].ToString(); string subStr = propVal.Substring(propVal.Length / 2); url = string.Format("{0}?$filter=contains({1}, '{2}')", url, propName, subStr); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { jObj = JObject.Parse(resp.ResponsePayload); jArr = jObj.GetValue(Constants.Value) as JArray; foreach (JObject et in jArr) { passed = et[propName].ToString().Contains(subStr); } } else { passed = false; detail.ErrorMessage = "The server returned an error response: " + detail.ResponseStatusCode; } } return(passed); }
/// <summary> /// Initialize the data factory. /// </summary> private DataFactory() { ServiceStatus serviceStatus = ServiceStatus.GetInstance(); this.rootURL = serviceStatus.RootURL; this.serviceDoc = serviceStatus.ServiceDocument; this.metadataDoc = serviceStatus.MetadataDocument; }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var navigPropNames = MetadataHelper.GetNavigationPropertyNames( out entityTypeShortName, null, (elem) => { return(!(null != elem.Attribute("Nullable") && elem.GetAttributeValue("Nullable") == "false")); }); if (null == navigPropNames || !navigPropNames.Any()) { return(passed); } string navigPropName = navigPropNames[0]; navigPropNames.RemoveAt(0); var entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = string.Format("{0}/{1}?$expand={2}", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, navigPropName); var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionExpand", url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue("value") as JArray; foreach (JObject entity in jArr) { passed = false; foreach (JProperty prop in entity.Children()) { if (prop.Name == navigPropName) { passed = true; break; } } if (passed == true) { break; } } } return(passed); }
/// <summary> /// Get property type and type class. /// </summary> /// <param name="entityTypeShortName"> The short name of entity type.</param> /// <param name="propertyName">The name of the property in the entity type.</param> /// <returns>The key value pair in which key is the property type short name and the value is the property type class.</returns> private KeyValuePair <string, PropertyTypeClass>?GetPropertyTypeClass(string entityTypeShortName, string propertyName) { string pattern = "//*[local-name()='EntityType' and @Name='{0}']/*[local-name()='Property' and @Name='{1}']"; string metadataString = ServiceStatus.GetInstance().MetadataDocument; var metadata = XElement.Parse(metadataString); string xPath = string.Format(pattern, entityTypeShortName, propertyName); XElement prop = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (prop == null) { return(null); } string propType = prop.GetAttributeValue("Type"); string propTypeShortName = propType.RemoveCollectionFlag().GetLastSegment(); PropertyTypeClass typeClass = PropertyTypeClass.Unknown; string type = propTypeShortName; if (propType.Contains("Collection(")) { typeClass = PropertyTypeClass.CollectionType; } else if (EdmTypeManager.IsEdmSimpleType(propType)) { typeClass = PropertyTypeClass.PrimitiveType; type = propType; } else { xPath = string.Format("//*[@Name = '{0}']", propTypeShortName); XElement typeDefElement = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (typeDefElement == null) { return(null); } switch (typeDefElement.Name.LocalName) { case "ComplexType": typeClass = PropertyTypeClass.ComplexType; break; case "EnumType": typeClass = PropertyTypeClass.EnumType; break; default: typeClass = PropertyTypeClass.Unknown; break; } } return(new KeyValuePair <string, PropertyTypeClass>(type, typeClass)); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propTypes = new string[1] { "Edm.DateTimeOffset" }; var propNames = MetadataHelper.GetPropertyNames(propTypes, out entityTypeShortName); if (null == propNames || !propNames.Any()) { return(passed); } string propName = propNames[0]; var entitySetUrl = entityTypeShortName.GetAccessEntitySetURL(); if (string.IsNullOrEmpty(entitySetUrl)) { return(passed); } string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { url = string.Format("{0}?$filter={1} le maxdatetime()", url, propName); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { passed = true; } else { detail.ErrorMessage = "The server returned an error response: " + detail.ResponseStatusCode; passed = false; } } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propNames = MetadataHelper.GetNumericPropertyNames(out entityTypeShortName); string propName = propNames[0]; if (string.IsNullOrEmpty(entityTypeShortName) || string.IsNullOrEmpty(propName)) { return(passed); } string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); // Set the negative number as -5.0. It is only a testing number, so it can be any numbers. double negativeNum = -5.0; string url = string.Format("{0}/{1}?$filter={2} gt -({3})", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, propName, negativeNum); var resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue(Constants.Value); passed = true; foreach (JObject entity in jArr) { try { double val = Convert.ToDouble(entity[propName]); if (val <= -negativeNum) { passed = false; break; } } catch (Exception) { return(null); } } } else { passed = false; } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var propNames = MetadataHelper.GetPropertyNames(out entityTypeShortName); if (null == propNames || !propNames.Any()) { return(passed); } string propName = propNames[0]; propNames.RemoveAt(0); var entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = string.Format("{0}/{1}?$select={2}", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, propName); var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionSelect", url, HttpMethod.Get, string.Empty); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue("value") as JArray; foreach (JObject entity in jArr) { foreach (JProperty prop in entity.Children()) { passed = true; if (propNames.Contains(prop.Name)) { detail.ErrorMessage = propNames + " does not contain " + prop.Name; passed = false; break; } } } } return(passed); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var keyProp = MetadataHelper.GetKeyProperty(out entityTypeShortName); if (null == keyProp) { return(passed); } string keyPropName = keyProp.Item1; string keyPropType = keyProp.Item2; if (string.IsNullOrEmpty(entityTypeShortName) || string.IsNullOrEmpty(keyPropName) || string.IsNullOrEmpty(keyPropType)) { return(passed); } string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); string url = string.Format("{0}/{1}?$orderby={2} desc", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, keyPropName); var resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionOrderBy", url, HttpMethod.Get, resp.ResponseHeaders, resp); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); //public ExtensionRuleResultDetail(string ruleName, string uri, string httpMethod, string requestHeaders, string responseStatusCode = "", string responseHeaders = "", string responsePayload = "", string errorMessage = "", string requestData = "") info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { var jObj = JObject.Parse(resp.ResponsePayload); var jArr = jObj.GetValue("value") as JArray; passed = true; for (int i = 0; i < jArr.Count - 1; i++) { if (!CompareOperationHelper.Compare(jArr[i][keyPropName], jArr[i + 1][keyPropName], keyPropType, ComparerType.Equal | ComparerType.GreaterThan)) { passed = false; break; } } } return(passed); }
/// <summary> /// Map navigation property name to its related entity-set name. /// </summary> /// <param name="navigationPropertyName">A navigation property name.</param> /// <param name="entityTypeShortName">An entity-type short name which contains specifed navigation property name.</param> /// <returns>Returns the related entity-set name.</returns> public static string MapNavigationPropertyNameToEntitySetName(this string navigationPropertyName, string entityTypeShortName) { if (string.IsNullOrEmpty(navigationPropertyName)) { throw new ArgumentNullException(string.Format(ParamNullErrorMsgPattern, "navigationPropertyName")); } if (string.IsNullOrEmpty(entityTypeShortName)) { throw new ArgumentNullException(string.Format(ParamNullErrorMsgPattern, "entityTypeShortName")); } if (!IsSpecifiedEntityTypeShortNameExist(entityTypeShortName)) { throw new ArgumentException(string.Format(ParamNotFoundErrorMsgPattern, "entity-type", "short name", "entityTypeShortName")); } //string entitySetURL = string.Empty; var metadata = XElement.Parse(ServiceStatus.GetInstance().MetadataDocument); string xPath = string.Format("//*[local-name()='EntityType' and @Name='{0}']/*[local-name()='NavigationProperty' and @Name='{1}']", entityTypeShortName, navigationPropertyName); var navigationPropertyElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (null != navigationPropertyElem) { var navigationPropertyType = null != navigationPropertyElem.Attribute("Type") ? navigationPropertyElem.GetAttributeValue("Type") : string.Empty; if (!string.IsNullOrEmpty(navigationPropertyType)) { return(navigationPropertyType // Remove the collection flag from navigation property type, in order to map it to entity-type full name. .RemoveCollectionFlag() // Map the entity-type full name to entity-set name. .MapEntityTypeFullNameToEntitySetName()); } } else { xPath = string.Format("//*[local-name()='EntityType' and @Name='{0}']", entityTypeShortName); navigationPropertyElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (null != navigationPropertyElem.Attribute("BaseType")) { string baseEntityTypeShortName = navigationPropertyElem.GetAttributeValue("BaseType").GetLastSegment(); return(MapNavigationPropertyNameToEntitySetName(navigationPropertyName, baseEntityTypeShortName)); } else { throw new ArgumentException(string.Format(ParamNotFoundErrorMsgPattern, "navigation property", "name", "navigationPropertyName")); } } return(string.Empty); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entityTypeShortName; var keyProp = MetadataHelper.GetKeyProperty(out entityTypeShortName); if (null == keyProp || string.IsNullOrEmpty(entityTypeShortName)) { return(passed); } string keyPropName = keyProp.Item1; string keyPropType = keyProp.Item2; string entitySetUrl = entityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); if (string.IsNullOrEmpty(entitySetUrl)) { return(passed); } string url = svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl; var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { return(passed); } var jObj = JObject.Parse(resp.ResponsePayload); string keyPropVal = jObj.GetValue(Constants.Value).First[keyPropName].ToString(); string pattern = "Edm.String" == keyPropType ? "{0}/$entity?$id={1}('{2}')" : "{0}/$entity?$id={1}({2})"; url = string.Format(pattern, svcStatus.RootURL.TrimEnd('/'), svcStatus.RootURL.TrimEnd('/') + "/" + entitySetUrl, keyPropVal); resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail("ServiceImpl_SystemQueryOptionEntity_Id", url, HttpMethod.Get, string.Empty); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { passed = true; } else { passed = false; } return(passed); }
/// <summary> /// Get specified count of entities from first feed of service document. /// </summary> /// <param name="context">The service document context.</param> /// <returns>Returns an entity URLs's list.</returns> public static bool GetBatchSupportedEntityUrls(out KeyValuePair <string, IEnumerable <string> > entityUrls) { entityUrls = new KeyValuePair <string, IEnumerable <string> >(); var svcStatus = ServiceStatus.GetInstance(); List <string> vocDocs = new List <string>() { TermDocuments.GetInstance().VocCapabilitiesDoc }; var payloadFormat = svcStatus.ServiceDocument.GetFormatFromPayload(); var batchSupportedEntitySetUrls = new List <string>(); var batchSupportedEntitySetNames = AnnotationsHelper.SelectEntitySetSupportBatch(svcStatus.MetadataDocument, vocDocs); batchSupportedEntitySetNames.ForEach(temp => { batchSupportedEntitySetUrls.Add(temp.MapEntitySetNameToEntitySetURL()); }); var entitySetUrls = ContextHelper.GetFeeds(svcStatus.ServiceDocument, payloadFormat).ToArray(); if (entitySetUrls.Any()) { string entitySetUrl = string.Empty; foreach (var setUrl in entitySetUrls) { try { string entityTypeShortName = setUrl.MapEntitySetURLToEntityTypeShortName(); if (batchSupportedEntitySetUrls.Contains(setUrl) && !entityTypeShortName.IsMediaType()) { entitySetUrl = setUrl; break; } } catch (Exception ex) { throw ex; string test = ex.Message; } } if (string.IsNullOrEmpty(entitySetUrl)) { return(false); } string url = string.Format("{0}/{1}?$top=1", svcStatus.RootURL.TrimEnd('/'), entitySetUrl); Response response = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); payloadFormat = response.ResponsePayload.GetFormatFromPayload(); var payloadType = ContextHelper.GetPayloadType(response.ResponsePayload, payloadFormat, response.ResponseHeaders); if (payloadType == RuleEngine.PayloadType.Feed) { entityUrls = new KeyValuePair <string, IEnumerable <string> >(entitySetUrl, ContextHelper.GetEntries(response.ResponsePayload, payloadFormat)); return(true); } } return(false); }
public static DataFactory Instance() { // Initialize the increment of the property's key to 1. keyIncrement = 1; if (null == factory || ServiceStatus.GetInstance().RootURL != factory.rootURL) { factory = new DataFactory(); } return(factory); }
/// <summary> /// Verifies the service implementation feature. /// </summary> /// <param name="context">The Interop service context</param> /// <param name="info">out parameter to return violation information when rule does not pass</param> /// <returns>true if the service implementation feature passes; false otherwise</returns> public override bool?Verify(ServiceContext context, out ExtensionRuleViolationInfo info) { if (context == null) { throw new ArgumentNullException("context"); } bool?passed = null; info = null; var svcStatus = ServiceStatus.GetInstance(); string entitySetUrl = MetadataHelper.GetEntitySetURLs().First(); string entityTypeFullName = entitySetUrl.MapEntitySetURLToEntityTypeFullName(); string url = string.Format("{0}/{1}?$filter=isof('{2}')", svcStatus.RootURL.TrimEnd('/'), entitySetUrl, entityTypeFullName); var resp = WebHelper.Get(new Uri(url), string.Empty, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, svcStatus.DefaultHeaders); var detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, string.Empty); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); info = new ExtensionRuleViolationInfo(new Uri(url), string.Empty, detail); if (null != resp && HttpStatusCode.OK == resp.StatusCode) { JObject jObj = JObject.Parse(resp.ResponsePayload); JArray jArr = jObj.GetValue(Constants.Value) as JArray; foreach (JObject entity in jArr) { if (null == entity[Constants.V4OdataType]) { passed = true; } else { passed = entity[Constants.V4OdataType].ToString() == entityTypeFullName; if (passed == false) { detail.ErrorMessage = entity[Constants.V4OdataType].ToString() + " not equal to " + entityTypeFullName; break; } } } } else { detail.ErrorMessage = "The server returned an error response: " + detail.ResponseStatusCode; passed = false; } return(passed); }
/// <summary> /// Verify whether a singleton is existent in the service. /// </summary> /// <param name="singletonName">A singleton name.</param> /// <returns>Returns true if exist, otherwise false.</returns> public static bool IsSpecifiedSingletonNameExist(this string singletonName) { if (string.IsNullOrEmpty(singletonName)) { return(false); } var metadata = XElement.Parse(ServiceStatus.GetInstance().MetadataDocument); string xPath = string.Format("//*[local-name()='Singleton' and @Name='{0}']", singletonName); var singletonElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); return(null != singletonElem); }
/// <summary> /// Verify whether a contained navigation property is existent in the service. /// </summary> /// <param name="navigPropName">A navigation property name.</param> /// <returns>Returns true if exist, otherwise false.</returns> public static bool IsSpecifiedContainedNavigPropExist(this string navigPropName) { if (string.IsNullOrEmpty(navigPropName)) { return(false); } var metadata = XElement.Parse(ServiceStatus.GetInstance().MetadataDocument); string xPath = string.Format("//*[local-name()='NavigationProperty' and @Name='{0}' and @ContainsTarget='true']", navigPropName); var navigPropElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); return(null != navigPropElem); }
/// <summary> /// Get accessable key properties from entity-type. /// </summary> /// <param name="entityTypeShortName">The entity-type short name.</param> /// <returns>Returns the accessable key properties.</returns> private static List <Tuple <string, string> > GetAccessKeyPropertiesET(this string entityTypeShortName) { if (string.IsNullOrEmpty(entityTypeShortName)) { throw new ArgumentNullException(string.Format(ParamNullErrorMsgPattern, "entityTypeShortName")); } var result = new List <Tuple <string, string> >(); var svcStatus = ServiceStatus.GetInstance(); var metadata = XElement.Parse(svcStatus.MetadataDocument); string xPath = string.Format("//*[local-name()='EntityType' and @Name='{0}']", entityTypeShortName); var entityTypeElem = metadata.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (null != entityTypeElem) { xPath = "./*[local-name()='Key']/*[local-name()='PropertyRef']"; var propRefElems = entityTypeElem.XPathSelectElements(xPath, ODataNamespaceManager.Instance); if (null != propRefElems && propRefElems.Any()) { foreach (var elem in propRefElems) { if (null == elem.Attribute("Name")) { continue; } string propName = elem.GetAttributeValue("Name"); xPath = string.Format("./*[local-name()='Property' and @Name='{0}']", propName); var propElem = entityTypeElem.XPathSelectElement(xPath, ODataNamespaceManager.Instance); if (null == propElem || null == propElem.Attribute("Type")) { continue; } string propType = propElem.GetAttributeValue("Type"); result.Add(new Tuple <string, string>(propName, propType)); } return(result); } else if (null != entityTypeElem.Attribute("BaseType")) { string baseTypeShortName = entityTypeElem.GetAttributeValue("BaseType").GetLastSegment(); return(MappingHelper.GetAccessKeyPropertiesET(baseTypeShortName)); } } return(result); }