/// <summary> /// Verifies the extension rule. /// </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 rule 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; ServiceStatus serviceStatus = ServiceStatus.GetInstance(); DataFactory dFactory = DataFactory.Instance(); var detail = new ExtensionRuleResultDetail(this.Name, serviceStatus.RootURL, HttpMethod.Post, string.Empty); List <string> keyPropertyTypes = new List <string>() { "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String" }; List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.None).ToList(); if (null == entityTypeElements || 0 == entityTypeElements.Count()) { detail.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property, but there is no this entity type in metadata so can not verify this rule."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } EntityTypeElement eTypeElement = null; NormalProperty prop = null; string propReltivePath = string.Empty; foreach (var en in entityTypeElements) { foreach (NormalProperty np in en.NormalProperties) { if (!np.IsKey && !en.HasStream && np.IsNullable) { eTypeElement = en; prop = np; if (!np.PropertyType.Contains("Collection(") && np.PropertyType.Contains("Edm.")) { propReltivePath = prop.PropertyName + @"/$value"; } else { propReltivePath = prop.PropertyName; } break; } } if (prop != null) { break; } } if (eTypeElement == null || string.IsNullOrEmpty(eTypeElement.EntitySetName)) { detail.ErrorMessage = "Cannot find the appropriate entity-set URL to verify this rule."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } string url = serviceStatus.RootURL.TrimEnd('/') + @"/" + eTypeElement.EntitySetName; var additionalInfos = new List <AdditionalInfo>(); var reqData = dFactory.ConstructInsertedEntityData(eTypeElement.EntitySetName, eTypeElement.EntityTypeShortName, null, out additionalInfos); if (!dFactory.CheckOrAddTheMissingPropertyData(eTypeElement.EntitySetName, prop.PropertyName, ref reqData)) { detail.ErrorMessage = "The property to delete does not have value, and cannot be deleted."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } ; string reqDataStr = reqData.ToString(); if (reqDataStr.Length > 2) { bool isMediaType = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag); var resp = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos); detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr); if (HttpStatusCode.Created == resp.StatusCode || HttpStatusCode.NoContent == resp.StatusCode) { url = additionalInfos.Last().EntityId.TrimEnd('/') + "/" + propReltivePath; if (!Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute)) { detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr); // Restore the service. var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos); return(passed); } resp = WebHelper.Get(new Uri(url), null, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, null); detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Get, StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, serviceStatus.DefaultHeaders), resp); if ((resp.StatusCode.HasValue && HttpStatusCode.OK == resp.StatusCode) || HttpStatusCode.NoContent == resp.StatusCode) { resp = WebHelper.DeleteEntity(url, context.RequestHeaders, additionalInfos.Last().HasEtag); detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Delete, string.Empty, resp, string.Empty, "Successfully updated the stream of the image."); if (null != resp && (HttpStatusCode.NoContent == resp.StatusCode)) { passed = true; } else { passed = false; detail.ErrorMessage = string.Format("HTTP delete to delete the structural or primitive property value to null failed with the error {0}.", resp.StatusCode); } } else { detail.ErrorMessage = "Get property failed from above URI."; } // Restore the service. WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos); } else { detail.ErrorMessage = "Created the new entity failed for above URI."; } } else { detail.ErrorMessage = "Constructing the new entity to create failed."; } var details = new List <ExtensionRuleResultDetail>() { detail }; info = new ExtensionRuleViolationInfo(new Uri(url), serviceStatus.ServiceDocument, details); return(passed); }
/// <summary> /// Verifies the extension rule. /// </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 rule 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; ServiceStatus serviceStatus = ServiceStatus.GetInstance(); TermDocuments termDocs = TermDocuments.GetInstance(); DataFactory dFactory = DataFactory.Instance(); ExtensionRuleResultDetail detail1 = new ExtensionRuleResultDetail(this.Name); ExtensionRuleResultDetail detail2 = new ExtensionRuleResultDetail(this.Name); List <string> keyPropertyTypes = new List <string>() { "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String" }; List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.CollectionValued).ToList(); if (entityTypeElements == null || entityTypeElements.Count == 0) { detail1.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property, but there is no this entity type in metadata so can not verify this rule."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail1); return(passed); } foreach (var et in entityTypeElements) { var matchEntity = et.EntitySetName.GetRestrictions(serviceStatus.MetadataDocument, termDocs.VocCapabilitiesDoc, new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >() { AnnotationsHelper.GetDeleteRestrictions, AnnotationsHelper.GetInsertRestrictions }); if (string.IsNullOrEmpty(matchEntity.Item1) || matchEntity.Item2 == null || !matchEntity.Item2.Any() || matchEntity.Item3 == null || !matchEntity.Item3.Any()) { continue; } string navigPropName = null; string navigPropRelatedEntityTypeShortName = null; string navigPropRelatedEntitySetName = null; string navigPropRelatedEntitySetUrl = null; NormalProperty navigPropRelatedEntityTypeKey = null; foreach (var np in matchEntity.Item3) { navigPropName = np.NavigationPropertyName; navigPropRelatedEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); List <NormalProperty> navigKeyProps = MetadataHelper.GetKeyProperties(serviceStatus.MetadataDocument, navigPropRelatedEntityTypeShortName).ToList(); if (navigKeyProps.Count == 1 && keyPropertyTypes.Contains(navigKeyProps[0].PropertyType)) { navigPropRelatedEntitySetName = navigPropRelatedEntityTypeShortName.MapEntityTypeShortNameToEntitySetName(); navigPropRelatedEntitySetUrl = navigPropRelatedEntityTypeShortName.MapEntityTypeShortNameToEntitySetURL(); navigPropRelatedEntityTypeKey = navigKeyProps[0]; break; } } if (null != navigPropRelatedEntityTypeKey && !string.IsNullOrEmpty(navigPropRelatedEntitySetUrl)) { string entitySetUrl = et.EntitySetName.MapEntitySetNameToEntitySetURL(); string url = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl; var additionalInfos1 = new List <AdditionalInfo>(); var reqData = dFactory.ConstructInsertedEntityData(et.EntitySetName, et.EntityTypeShortName, null, out additionalInfos1); string reqDataStr = reqData.ToString(); bool isMediaType = !string.IsNullOrEmpty(additionalInfos1.Last().ODataMediaEtag); var resp = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos1); detail1 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr); if (resp.StatusCode.HasValue && HttpStatusCode.Created == resp.StatusCode) { string entityId = additionalInfos1.Last().EntityId; url = serviceStatus.RootURL.TrimEnd('/') + @"/" + navigPropRelatedEntitySetUrl; if (string.IsNullOrEmpty(navigPropRelatedEntityTypeShortName)) { continue; } var navigPropEntityType = navigPropRelatedEntityTypeShortName.GetSpecifiedEntityType(serviceStatus.MetadataDocument); if (null == navigPropEntityType) { continue; } url = string.Format("{0}/{1}", entityId, navigPropName); var additionalInfos2 = new List <AdditionalInfo>(); reqData = dFactory.ConstructInsertedEntityData(navigPropRelatedEntitySetName, navigPropRelatedEntityTypeShortName, null, out additionalInfos2); reqDataStr = reqData.ToString(); isMediaType = !string.IsNullOrEmpty(additionalInfos2.Last().ODataMediaEtag); resp = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos2); detail2 = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr); if (resp.StatusCode.HasValue && resp.StatusCode == HttpStatusCode.Created) { passed = true; // Restore the service. var resps2 = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos2); } else { passed = false; detail2.ErrorMessage = "Create entity failed for above URI."; } // Restore the service. var resps1 = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos1); } else { passed = false; detail1.ErrorMessage = "Created the new entity failed for above URI."; } } if (false == passed) { break; } } var details = new List <ExtensionRuleResultDetail>() { detail1, detail2 }.RemoveNullableDetails(); info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, details); return(passed); }
/// <summary> /// Verifies the extension rule. /// </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 rule 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; ServiceStatus serviceStatus = ServiceStatus.GetInstance(); DataFactory dFactory = DataFactory.Instance(); var detail = new ExtensionRuleResultDetail(this.Name, serviceStatus.RootURL, HttpMethod.Post, string.Empty); string updateUrl = serviceStatus.RootURL; List <string> keyPropertyTypes = new List <string>() { "Edm.Int32", "Edm.Int16", "Edm.Int64", "Edm.Guid", "Edm.String" }; List <string> norPropertyTypes = new List <string>() { "Edm.String" }; List <EntityTypeElement> entityTypeElements = MetadataHelper.GetEntityTypes(serviceStatus.MetadataDocument, 1, keyPropertyTypes, null, NavigationRoughType.None).ToList(); if (null == entityTypeElements || 0 == entityTypeElements.Count) { detail.ErrorMessage = "To verify this rule it expects an entity type with Int32/Int64/Int16/Guid/String key property and a string type normal property, but there is no this entity type in metadata so can not verify this rule."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } EntityTypeElement entityType = null; NormalProperty primitiveProp = null; foreach (var en in entityTypeElements) { foreach (NormalProperty np in en.NormalProperties) { if (!np.IsKey && np.PropertyType.Equals("Edm.String")) { entityType = en; primitiveProp = np; break; } } if (primitiveProp != null) { break; } } if (entityType == null) { detail.ErrorMessage = "To verify this rule it expects an Edm.String type property in an entity, but there is no such entity in metadata. So can not verify this rule."; info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } string entitySetUrl = entityType.EntitySetName.MapEntitySetNameToEntitySetURL(); updateUrl = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl; if (string.IsNullOrEmpty(entitySetUrl)) { detail.ErrorMessage = string.Format("Cannot find the entity-set URL which is matched with {0}", entityType.EntityTypeShortName); info = new ExtensionRuleViolationInfo(new Uri(serviceStatus.RootURL), serviceStatus.ServiceDocument, detail); return(passed); } string url = serviceStatus.RootURL.TrimEnd('/') + @"/" + entitySetUrl; var additionalInfos = new List <AdditionalInfo>(); var reqData = dFactory.ConstructInsertedEntityData(entityType.EntitySetName, entityType.EntityTypeShortName, null, out additionalInfos); string reqDataStr = reqData.ToString(); if (reqDataStr.Length > 2) { bool isMediaType = !string.IsNullOrEmpty(additionalInfos.Last().ODataMediaEtag); var resp = WebHelper.CreateEntity(url, context.RequestHeaders, reqData, isMediaType, ref additionalInfos); detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Post, string.Empty, resp, string.Empty, reqDataStr); if (HttpStatusCode.Created == resp.StatusCode) { string entityId = additionalInfos.Last().EntityId; updateUrl = entityId.TrimEnd('/') + "/" + primitiveProp.PropertyName + @"/$value"; bool hasEtag = additionalInfos.Last().HasEtag; resp = WebHelper.GetPropertyValue(updateUrl); detail = new ExtensionRuleResultDetail(this.Name, entityId, HttpMethod.Get, string.Empty, resp); if (HttpStatusCode.OK == resp.StatusCode) { resp = WebHelper.UpdateAStringProperty(updateUrl, context.RequestHeaders, hasEtag); detail = new ExtensionRuleResultDetail(this.Name, url, HttpMethod.Put, string.Empty, resp, string.Empty, reqDataStr); if (HttpStatusCode.NoContent == resp.StatusCode) { resp = WebHelper.GetPropertyValue(updateUrl); detail = new ExtensionRuleResultDetail(this.Name, entityId, HttpMethod.Get, string.Empty, resp, string.Empty, reqDataStr); if (HttpStatusCode.OK == resp.StatusCode) { if (resp.ResponsePayload == Constants.UpdateData) { passed = true; } else { passed = false; detail.ErrorMessage = string.Format("The primitive property in request is not updated."); } } else { passed = false; detail.ErrorMessage = "Can not get the updated entity."; } } else { passed = false; detail.ErrorMessage = "Put the primitive property failed."; } } else { detail.ErrorMessage = "Can not get the created entity from above URI."; } // Restore the service. var resps = WebHelper.DeleteEntities(context.RequestHeaders, additionalInfos); } else { detail.ErrorMessage = "Created the new entity failed for above URI."; } } else { detail.ErrorMessage = "Constructing the testing entity failed."; } var details = new List <ExtensionRuleResultDetail>() { detail }; info = new ExtensionRuleViolationInfo(new Uri(updateUrl), serviceStatus.ServiceDocument, details); return(passed); }
set => SetValue(NormalProperty, value);