private void AddAnnotation(object sender, RoutedEventArgs e) { // add annotation based on button's tag value. Button button = (Button)sender; string actionName = button.Tag as string; if (this.document != null && this.document.NativePage != null && this.document.Page != null) { if (actionName == "star") { Annotation starAnnotation = new RubberStampAnnotation(new Boundary(10, 400, 50, 440), AnnotationFlags.Default); FixedContent fixedContent = new FixedContent("ap01", new Boundary(0, 0, 40, 40)); fixedContent.Content.AppendImage("star", 0, 0, 40, 40); starAnnotation.Appearance.Normal = fixedContent; this.document.NativePage.Annotations.Add(starAnnotation); this.document.PageViewModel.Annotations.Add(new StarAnnotationViewModel(starAnnotation, this.document.Page)); } else if (actionName == "smile") { Annotation starAnnotation = new RubberStampAnnotation(new Boundary(60, 400, 100, 440), AnnotationFlags.Default); FixedContent fixedContent = new FixedContent("ap01", new Boundary(0, 0, 40, 40)); fixedContent.Content.AppendImage("smile", 0, 0, 40, 40); starAnnotation.Appearance.Normal = fixedContent; this.document.NativePage.Annotations.Add(starAnnotation); this.document.PageViewModel.Annotations.Add(new SmileAnnotationViewModel(starAnnotation, this.document.Page)); } else if (actionName == "text") { FreeTextAnnotation textAnnotation = new FreeTextAnnotation(new Boundary(60, 400, 260, 500)); string sampleText = "sample text"; textAnnotation.Appearance.Normal = AnnotationsHelper.CreateNormalAppearance(sampleText, 200, 100); // set properties affecting default appearance to be used as fallback textAnnotation.FontSize = 12; textAnnotation.BorderEffect = new AnnotationBorderEffect(AnnotationBorderEffectStyle.NoEffect, 0); textAnnotation.Contents = sampleText; // text and border color textAnnotation.TextColor = RgbColors.White.Components; // set background here if needed textAnnotation.Color = RgbColors.Green.Components; this.document.NativePage.Annotations.Add(textAnnotation); this.document.PageViewModel.Annotations.Add(new TextAnnotationViewModel(textAnnotation, this.document.Page)); } } }
/// <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); }
private void OnHostShutdownTriggered() { log.Info("Hosting shutdown has been initiated. Timeout = {HostingShutdownTimeout}.", totalTimeout); if (sendAnnotation) { AnnotationsHelper.ReportStopping(identity, instanceMetrics); } hostShutdownBudget.Start(); ShutdownBeaconAsync().ContinueWith(_ => appShutdown.Initiate(hostShutdownBudget.Remaining)); }
public void checkJavaAttributesDeserialization() { if (File.Exists(expectedSpringMvcAttributeXmlFile) == false) { File.Delete(expectedSpringMvcAttributeXmlFile); AnnotationsHelper.executeJythonScript(testSpringMvcClassFile); } Assert.That(File.Exists(expectedSpringMvcAttributeXmlFile), "expectedSpringMvcAttributeXmlFile file did not exist: {0}", expectedSpringMvcAttributeXmlFile); var javaAttributeMappings = Serialize.getDeSerializedObjectFromXmlFile(expectedSpringMvcAttributeXmlFile, typeof(JavaAttributeMappings)); Assert.That(javaAttributeMappings != null, "javaAttributeMappings was null"); Assert.That(checkThatDeSerializedObjectMatchesXmlFile(expectedSpringMvcAttributeXmlFile, javaAttributeMappings), "checkThatDeSerializedObjectMatchesXmlFile failed"); DI.log.info("All ok"); }
/*private void handleDrop(DragEventArgs e) * { * O2Thread.mtaThread( * ()=> * { * var fileOrFolder = Dnd.tryToGetFileOrDirectoryFromDroppedObject(e); * * if (false == loadCirDataFile(fileOrFolder)) * // if (false == loadReferenceFindings(fileOrFolder)) * loadFileOrFolder(fileOrFolder); * }); * }*/ private void handleDropOnDropControl(object oObject, bool processJarFiles, bool deleteTempFiles) { var workingOnTaskFormName = "Running Spring MVC (Annotations) Analysis Engine"; O2AscxGUI.workingOnTaskForm_open(workingOnTaskFormName); O2Thread.mtaThread( () => { Processes.Sleep(500); try { O2AscxGUI.workingOnTaskForm_setText(workingOnTaskFormName, "Prepare files for Analysis (unzip zip, jars, etc..)"); var pythonStringTargetFileOrFolder = AnnotationsHelper.getPythonStringTargetFileOrFolder(oObject.ToString(), processJarFiles); //var tempFolder = DI.config.getTempFolderInTempDirectory("unzipedDroppedZip"); O2AscxGUI.workingOnTaskForm_setText(workingOnTaskFormName, "Converting files (using Jyhton)"); var tempFolderForAnnotationsXmlFiles = AnnotationsHelper.createAnnotationsXmlFilesFromJavaClassFileOrFolder(pythonStringTargetFileOrFolder); var javaXmlFilesToProcess = AnnotationsHelper.calculateFilesToProcess(oObject.ToString(), tempFolderForAnnotationsXmlFiles); O2AscxGUI.workingOnTaskForm_setText(workingOnTaskFormName, "Creating CirData"); var cirData = createCirData(javaXmlFilesToProcess); O2AscxGUI.workingOnTaskForm_setText(workingOnTaskFormName, "Mapping Spring Mvc Controllers"); var springMvcControllers = createSpringMvcControlersObjectsFromXmlFiles(javaXmlFilesToProcess); springMvcMappings.loadMappedControllers(cirData, springMvcControllers); //showSpringMvcControllers(springMvcControllers); if (deleteTempFiles) { Files.deleteFolder(tempFolderForAnnotationsXmlFiles, true); Files.deleteFolder(pythonStringTargetFileOrFolder, true); } else { DI.log.info( "Temp files were not deleted: \n tempFolderForAnnotationsXmlFiles:{0}\n pythonStringTargetFileOrFolder:{1} ", tempFolderForAnnotationsXmlFiles, pythonStringTargetFileOrFolder); } O2AscxGUI.workingOnTaskForm_close(workingOnTaskFormName); } catch (Exception ex) { DI.log.error("in handleDropOnDropControl: {0}", ex.Message); } }); }
[Test] // the errors that will appear in the logs are because we are not loading the CIR data file, for example "getTreeNodeWithAutoWiredObject, loaded cirData did not contained signature :org.springframework.samples.petclinic.web.EditOwnerForm.setupForm(int;org.springframework.ui.Model):java.lang.String" public void viewSpringMvcControllersObjectOnGui() { if (false == File.Exists(expectedSpringMvcAttributeXmlFile)) { AnnotationsHelper.executeJythonScript(testSpringMvcClassFile); } // create controllers var springMvcControllers = LoadSpringMvcData.createSpringMvcControllersFromXmlAttributeFile(expectedSpringMvcAttributeXmlFile); // create Gui var viewSpringMvcControllerName = "ascx_CreateSpringMvcMappings"; O2AscxGUI.openAscxAsForm(typeof(ascx_SpringMvcMappings), viewSpringMvcControllerName); var springMvcMappings = (ascx_SpringMvcMappings)O2AscxGUI.getAscx(viewSpringMvcControllerName); // load controllers on gui springMvcMappings.showSpringMvcControllers(springMvcControllers); O2AscxGUI.close(); //viewSpringMvcController }
private async Task <VostokApplicationRunResult> RunApplicationAsync() { log.Info("Running application."); ChangeStateTo(VostokApplicationState.Running); try { if (settings.SendAnnotations) { AnnotationsHelper.ReportInitialized(environment.ApplicationIdentity, environment.Metrics.Instance); } return(await RunPhaseAsync(false).ConfigureAwait(false)); } catch (Exception error) { log.Error(error, "Unhandled exception has occurred while running the application."); return(ReturnResult(VostokApplicationState.CrashedDuringRunning, error)); } }
public void convertClassFileInto() { // check that target class and Annotation.py exists Assert.That(File.Exists(testSpringMvcClassFile), "could not find test class to for test: {0}", testSpringMvcClassFile); Assert.That(File.Exists(AnnotationsHelper.jythonAnnotationScript), "could not find Annotations.py file {0}", AnnotationsHelper.jythonAnnotationScript); // exsure expectedSpringMvcAttributeXmlFile is not there if (File.Exists(expectedSpringMvcAttributeXmlFile)) { File.Delete(expectedSpringMvcAttributeXmlFile); } Assert.That(false == File.Exists(expectedSpringMvcAttributeXmlFile), "(at this stage) expected file should not exist: {0}", expectedSpringMvcAttributeXmlFile); // convert class file var executionResult = AnnotationsHelper.executeJythonScript(testSpringMvcClassFile); DI.log.debug("Execution Result: {0}", executionResult); Assert.That(File.Exists(expectedSpringMvcAttributeXmlFile), "expected file did not exist: {0}", expectedSpringMvcAttributeXmlFile); }
/// <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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var expandRestrictions = AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(expandRestrictions.Item1) || null == expandRestrictions.Item3 || !expandRestrictions.Item3.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = expandRestrictions.Item1; string navigProp = expandRestrictions.Item3.First().NavigationPropertyName; string url = string.Format("{0}/{1}", context.ServiceBaseUri, entitySet); var resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); info = new ExtensionRuleViolationInfo(new Uri(url), resp.ResponsePayload, detail); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); var entities = JsonParserHelper.GetEntries(feed); if (null == entities || 0 == entities.Count) { detail.ErrorMessage = string.Format("The entity-set {0} has no entity.", entitySet); info = new ExtensionRuleViolationInfo(new Uri(url), resp.ResponsePayload, detail); return(passed); } var entity = entities.First; string entityURL = null != entity[Constants.V4OdataId] ? entity[Constants.V4OdataId].ToString() : string.Empty; if (string.IsNullOrEmpty(entityURL)) { detail.ErrorMessage = "Cannot find the annotation @odata.id in the current entity."; info = new ExtensionRuleViolationInfo(new Uri(url), resp.ResponsePayload, detail); return(passed); } url = string.Format("{0}?$expand={1}/$ref", entityURL, navigProp); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject entry; resp.ResponsePayload.TryToJObject(out entry); if (entry != null && JTokenType.Object == entry.Type) { entity = entry[navigProp].First; url = entity[Constants.V4OdataId].ToString(); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (resp.StatusCode == HttpStatusCode.OK) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result, because the value of the annotation '@odata.id' is a bad link."; } } } else { passed = false; detail.ErrorMessage = "The service does not support the '$ref' segment for expanded properties."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var filterRestrictions = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string primitivePropType = filterRestrictions.Item2.First().PropertyType; string url = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); string propVal = "Edm.String" == primitivePropType?string.Format("'{0}'", entities[0][primitivePropName].ToString()) : entities[0][primitivePropName].ToString(); //var req = WebRequest.Create(string.Format("{0}?$filter={1} eq @test1&@test1={2}", url, primitivePropName, propVal)) as HttpWebRequest;; //resp = WebHelper.Get(req, RuleEngineSetting.Instance().DefaultMaximumPayloadSize); //REPLACE HEADER string requri = string.Format("{0}?$filter={1} eq @test1&@test1={2}", url, primitivePropName, propVal); resp = WebHelper.Get(requri, null, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, requri, "GET", string.Empty, resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject feed1; resp.ResponsePayload.TryToJObject(out feed1); if (feed1 != null && JTokenType.Object == feed1.Type) { var entities1 = JsonParserHelper.GetEntries(feed1).ToList(); var temp = entities1.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en); if (entities1.Count() == temp.Count()) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result on aliases in $filter expressions."; } } } else { passed = false; detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); } } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var restrictions = new Dictionary <string, Tuple <List <NormalProperty>, List <NavigProperty> > >(); if (!AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities, ref restrictions)) { detail.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (!AnnotationsHelper.IsSuitableNavigationProperty(NavigationRoughType.CollectionValued, ref restrictions)) { detail.ErrorMessage = "Cannot find any collection-valued navigation properties in any entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = string.Empty; string navigProp = string.Empty; foreach (var r in restrictions) { if (string.IsNullOrEmpty(r.Key) || null == r.Value.Item1 || !r.Value.Item1.Any() || null == r.Value.Item2 || !r.Value.Item2.Any()) { continue; } entitySet = r.Key; foreach (var np in r.Value.Item2) { navigProp = np.NavigationPropertyName; string nEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); var rest = AnnotationsHelper.GetCountRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(rest.Item1) || null == rest.Item2 || !rest.Item2.Any() || null == rest.Item3 || !rest.Item3.Any()) { continue; } break; } break; } if (string.IsNullOrEmpty(entitySet)) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (string.IsNullOrEmpty(navigProp)) { detail.ErrorMessage = "Cannot get expanded entities because cannot get collection type of navigation property from metadata"; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string url = string.Format("{0}/{1}?$expand={2}($count=true)", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, navigProp); Uri uri = new Uri(url); Response resp = WebHelper.Get(uri, Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, uri.AbsoluteUri, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); if (resp != null && resp.StatusCode == HttpStatusCode.OK) { JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (null == feed) { detail.ErrorMessage = "Cannot find any entity-sets in the service.\r\n"; info = new ExtensionRuleViolationInfo(uri, resp.ResponsePayload, detail); return(passed); } JObject entry = null; var entities = JsonParserHelper.GetEntries(feed); foreach (var e in entities) { if (null != e[navigProp] && JTokenType.Array == e[navigProp].Type) { entry = e as JObject; break; } } if (null == entry) { detail.ErrorMessage = "Cannot find an appropriate entity which contains at least one collection-valued navigation property.\r\n"; info = new ExtensionRuleViolationInfo(uri, resp.ResponsePayload, detail); return(passed); } if (null != entry && JTokenType.Object == entry.Type) { JArray jArr = entry[navigProp] as JArray; int actualAmount = 0; JsonParserHelper.GetEntitiesNumFromCollectionValuedNavigProp(entry[Constants.V4OdataId].ToString(), entry, navigProp, context.RequestHeaders, ref actualAmount); if (null != entry[navigProp + Constants.V4OdataCount] && actualAmount == (int)entry[navigProp + Constants.V4OdataCount]) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result on the system query option '$count' for expanded properties."; } } } else { passed = false; detail.ErrorMessage = "The service does not support the system query option '$count' for expanded properties."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; List <ExtensionRuleResultDetail> details = new List <ExtensionRuleResultDetail>(); ExtensionRuleResultDetail detail1 = new ExtensionRuleResultDetail(this.Name); Tuple <string, List <NormalProperty>, List <NavigProperty> > filterRestrictions = null; try { filterRestrictions = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities); } catch { detail1.ErrorMessage = "The Metadata is malformed. Cannot determine the entity-set that supports $filter"; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); passed = false; return(passed); } if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail1.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service. Check for Malformed Metadata"; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string primitivePropType = filterRestrictions.Item2.First().PropertyType; string url = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail1.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); string propVal = entities[0][primitivePropName].ToString(); #region Equal operation on filter. bool? isEqualOpValidation = null; string pattern = "Edm.String" == primitivePropType ? "{0}/{1}?$filter={2} eq '{3}'" : "{0}/{1}?$filter={2} eq {3}"; url = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail1 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject feed1; resp.ResponsePayload.TryToJObject(out feed1); if (feed1 != null && JTokenType.Object == feed1.Type) { var entities1 = JsonParserHelper.GetEntries(feed1).ToList(); var temp = entities1.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en); if (entities1.Count() == temp.Count()) { isEqualOpValidation = true; } else { isEqualOpValidation = false; detail1.ErrorMessage = "The service does not execute an accurate result with system query option $filter eq."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(isEqualOpValidation); } } } else { passed = false; detail1.ErrorMessage = "Request failed with system query option $filter eq."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } #endregion #region NotEqual operation on filter. bool?isNotEqualOpValidation = null; pattern = "Edm.String" == primitivePropType ? "{0}/{1}?$filter={2} ne '{3}'" : "{0}/{1}?$filter={2} ne {3}"; url = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); ExtensionRuleResultDetail detail2 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject feed2; resp.ResponsePayload.TryToJObject(out feed2); if (feed2 != null && JTokenType.Object == feed2.Type) { var entities2 = JsonParserHelper.GetEntries(feed2).ToList(); var temp = entities2.FindAll(en => propVal != en[primitivePropName].ToString()).Select(en => en); if (entities2.Count() == temp.Count()) { isNotEqualOpValidation = true; } else { isNotEqualOpValidation = false; detail2.ErrorMessage = "The service does not execute an accurate result with system query option $filter ne."; } } } else { passed = false; detail2.ErrorMessage = "Request failed with system query option $filter ne."; } #endregion if (true == isEqualOpValidation && true == isNotEqualOpValidation) { passed = true; } details.Add(detail2); } details.Insert(0, detail1); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, 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; List <string> vocDocs = new List <string>() { context.VocCapabilities, context.VocCore, context.VocMeasures }; List <string> expectedTypes = new List <string>() { "Edm.String", "Edm.Int32", "Edm.Int16", "Edm.Single", "Edm.Double", "Edm.Boolean", "Edm.DateTimeOffset", "Edm.Guid" }; List <ExtensionRuleResultDetail> details = new List <ExtensionRuleResultDetail>(); ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var restrictions = new Dictionary <string, Tuple <List <NormalProperty>, List <NavigProperty> > >(); if (!AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities, ref restrictions)) { detail.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (!AnnotationsHelper.IsSuitableNavigationProperty(NavigationRoughType.CollectionValued, ref restrictions)) { detail.ErrorMessage = "Cannot find any collection-valued navigation properties in any entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = string.Empty; string navigPropName = string.Empty; string primitivePropertyName = string.Empty; string primitivePropertyType = string.Empty; foreach (var r in restrictions) { if (string.IsNullOrEmpty(r.Key) || null == r.Value.Item1 || !r.Value.Item1.Any() || null == r.Value.Item2 || !r.Value.Item2.Any()) { continue; } foreach (var np in r.Value.Item2) { string nEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); string nEntitySetName = nEntityTypeShortName.MapEntityTypeShortNameToEntitySetName(); var funcs = new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >() { AnnotationsHelper.GetFilterRestrictions }; var rest = nEntitySetName.GetRestrictions(context.MetadataDocument, context.VocCapabilities, funcs, expectedTypes); if (string.IsNullOrEmpty(rest.Item1) || null == rest.Item2 || !rest.Item2.Any() || null == rest.Item3 || !rest.Item3.Any()) { continue; } navigPropName = np.NavigationPropertyName; primitivePropertyName = rest.Item2.First().PropertyName; primitivePropertyType = rest.Item2.First().PropertyType; break; } entitySet = r.Key; break; } if (string.IsNullOrEmpty(entitySet)) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (string.IsNullOrEmpty(navigPropName)) { detail.ErrorMessage = "Cannot get expanded entities because cannot get collection type of navigation property from metadata"; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (string.IsNullOrEmpty(primitivePropertyName) || string.IsNullOrEmpty(primitivePropertyType)) { detail.ErrorMessage = "Cannot get an appropriate primitive property from navigation properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string struri = string.Format("{0}/{1}?$expand={2}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, navigPropName); Uri uri = new Uri(struri); var response = WebHelper.Get(uri, Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (HttpStatusCode.OK != response.StatusCode) { passed = false; detail.ErrorMessage = JsonParserHelper.GetErrorMessage(response.ResponsePayload); info = new ExtensionRuleViolationInfo(uri, response.ResponsePayload, detail); return(passed); } JObject feed; response.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); var navigProp = entities[0][navigPropName] as JArray; if (navigProp != null && navigProp.Count != 0) { string propVal = navigProp[0][primitivePropertyName].ToString(); string compareVal = propVal; if (primitivePropertyType.Equals("Edm.String")) { compareVal = "'" + propVal + "'"; } string url = string.Format("{0}/{1}?$expand={2}($filter={3} eq {4})", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, navigPropName, primitivePropertyName, compareVal); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject jObj; resp.ResponsePayload.TryToJObject(out jObj); if (jObj != null && JTokenType.Object == jObj.Type) { var entries = JsonParserHelper.GetEntries(jObj).ToList(); foreach (var entry in entries) { if (entry[navigPropName] != null && ((JArray)entry[navigPropName]).Count == 0) { continue; } else if (entry[navigPropName] != null && ((JArray)entry[navigPropName]).Count > 0) { var temp = entry[navigPropName].ToList() .FindAll(en => propVal == en[primitivePropertyName].ToString()) .Select(en => en); if (entry[navigPropName].ToList().Count == temp.Count()) { passed = true; } else { passed = false; detail.ErrorMessage = string.Format("The service does not execute an accurate result on system query option '$filter' (Actual Value: {0}, Expected Value: {1}).", entry[navigPropName].ToList().Count, temp.Count()); break; } } } } } else { passed = false; detail.ErrorMessage = string.Format("The service does not support system query option '$filter' on expanded entities."); } } } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var restrictions = AnnotationsHelper.GetChangeTracking(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(restrictions.Item1) || null == restrictions.Item2 || !restrictions.Item2.Any() || null == restrictions.Item3 || !restrictions.Item3.Any()) { detail.ErrorMessage = "Cannot find an entity-container or any entity-sets which support the change tracking function."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string url = string.Format("{0}/{1}", context.ServiceBaseUri, restrictions.Item1); List <KeyValuePair <string, string> > requestHeaders = new List <KeyValuePair <string, string> >(); foreach (KeyValuePair <string, string> kvp in context.RequestHeaders) { requestHeaders.Add(new KeyValuePair <string, string>(kvp.Key, kvp.Value)); } // Add odata.track-changes preference in request header. KeyValuePair <string, string> prefer = new KeyValuePair <string, string>("Prefer", "odata.track-changes"); requestHeaders.Add(prefer); Response response = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, requestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, requestHeaders), response); if (response != null && !string.IsNullOrEmpty(response.ResponseHeaders)) { string preferHeader = response.ResponseHeaders.GetHeaderValue("Preference-Applied"); if (string.IsNullOrEmpty(preferHeader)) { passed = false; detail.ErrorMessage = "The response header returned by the service does not contain 'odata.track-changes', when request with the header 'Prefer:odata.track-changes'."; } else if (preferHeader.Contains("odata.track-changes")) { passed = true; } } else { passed = false; detail.ErrorMessage = "The service does not support Delta change tracking."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); detail = info.Details[0]; List <string> supportedPropertyTypes = new List <string> { PrimitiveDataTypes.Int16, PrimitiveDataTypes.Int32, PrimitiveDataTypes.Int64, PrimitiveDataTypes.Decimal, PrimitiveDataTypes.Double }; var filterRestrictions = AnnotationsHelper.GetFilterRestrictionsWithoutNavi(context.MetadataDocument, context.VocCapabilities, supportedPropertyTypes); if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports Greater Than system query options in the service."; return(passed); } string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string url = string.Format("{0}/{1}", context.ServiceBaseUri, entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed == null || JTokenType.Object != feed.Type) { detail.ErrorMessage = "The service does not return a valid response for system query option"; return(passed); } var entities = JsonParserHelper.GetEntries(feed); Int64 propVal = entities[0].Value <Int64>(primitivePropName) - 1; string pattern = "{0}/{1}?$filter={2} gt {3}"; url = string.Format(pattern, context.ServiceBaseUri, entitySet, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail.URI = url; detail.HTTPMethod = "GET"; detail.RequestHeaders = StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders); detail.ResponseStatusCode = resp != null && resp.StatusCode.HasValue ? resp.StatusCode.Value.ToString() : ""; detail.ResponseHeaders = string.IsNullOrEmpty(resp.ResponseHeaders) ? "" : resp.ResponseHeaders; detail.ResponsePayload = string.IsNullOrEmpty(resp.ResponsePayload) ? "" : resp.ResponsePayload; if (resp.StatusCode != HttpStatusCode.OK) { passed = false; detail.ErrorMessage = "Request failed with system query option $filter gt."; return(passed); } JObject feed2; resp.ResponsePayload.TryToJObject(out feed2); if (feed2 == null || JTokenType.Object != feed2.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option $filter gt."; return(passed); } var entities2 = JsonParserHelper.GetEntries(feed2).ToList(); var temp = entities2.FindAll(en => en.Value <Int64>(primitivePropName) > propVal).Select(en => en); if (entities2.Count() == temp.Count()) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter gt."; } 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var countRestrictions = AnnotationsHelper.GetCountRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(countRestrictions.Item1)) { detail.ErrorMessage = "Cannot find an entity-set which supports $count system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = countRestrictions.Item1; bool isNextLinkPropExist = false; Int64 totalCount = 0; string url = string.Format("{0}/{1}?$count=true", context.ServiceBaseUri.AbsoluteUri.TrimEnd('/'), entitySet); Response resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.V4AcceptHeaderJsonFullMetadata, context.RequestHeaders), resp); if (resp.StatusCode.HasValue && resp.StatusCode == HttpStatusCode.OK) { JObject feed; resp.ResponsePayload.TryToJObject(out feed); var entries = JsonParserHelper.GetEntries(feed); if (feed[Constants.V4OdataCount] != null) { totalCount = Convert.ToInt64(feed[Constants.V4OdataCount].Value <string>().StripOffDoubleQuotes()); if (entries.Count == totalCount) { passed = true; } else if (entries.Count < totalCount) { var jProps = feed.Children(); foreach (JProperty jProp in jProps) { if (jProp.Name == Constants.V4OdataNextLink) { isNextLinkPropExist = true; break; } } if (isNextLinkPropExist) { passed = true; } else { passed = false; detail.ErrorMessage = string.Format("The feed has {0} entities totally, but it only display {1} entities and there is no NextLink annotation.", totalCount, entries.Count); } } else { passed = null; detail.ErrorMessage = string.Format("The response of feed {0} has only one page, so can not test partial results.", entitySet); } } else { passed = null; detail.ErrorMessage = string.Format("The response of feed {0} does not have \"@Odata.count\" annotation so it cannot get the total count of entities.", entitySet); } } else { passed = null; detail.ErrorMessage = "Cannot get response from above URI."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var filterRestrictions = AnnotationsHelper.GetFilterRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string primitivePropType = filterRestrictions.Item2.First().PropertyType; string url = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); string propVal = "Edm.String" == primitivePropType?string.Format("{0}", entities[0][primitivePropName].ToString()) : entities[0][primitivePropName].ToString(); #region Equal operation on filter. url = string.Format("{0}?$filter={1} eq '{2}'", url, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp.StatusCode == HttpStatusCode.OK) { JObject jObj; resp.ResponsePayload.TryToJObject(out jObj); if (jObj != null && JTokenType.Object == jObj.Type) { var entries = JsonParserHelper.GetEntries(jObj).ToList(); var temp = entries.FindAll(en => propVal == en[primitivePropName].ToString()).Select(en => en); if (entries.Count() == temp.Count()) { passed = true; } else { passed = false; detail.ErrorMessage = string.Format("The actual result of filter operation is {0}, and the expected result of filter operation is {1}", entities.Count, temp.Count()); } } } else if (resp.StatusCode == HttpStatusCode.NotImplemented) { passed = true; } else { passed = false; detail.ErrorMessage = String.Format(JsonParserHelper.GetErrorMessage(resp.ResponsePayload)); } #endregion } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var restrictions = AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities); if (string.IsNullOrEmpty(restrictions.Item1) || null == restrictions.Item3 || !restrictions.Item3.Any()) { detail.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } // Set a expected level number as 2, and store it in the parameter expectedLevel. int expectedLevels = 2; string entitySetName = restrictions.Item1; string entityTypeShortName = entitySetName.MapEntitySetNameToEntityTypeShortName(); string[] navigPropNames = MetadataHelper.GetNavigPropNamesRecurseByLevels(entityTypeShortName, context.MetadataDocument, expectedLevels); string url = string.Format("{0}/{1}?$expand=*($levels={2})", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySetName, expectedLevels); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), resp); if (resp != null && resp.StatusCode == HttpStatusCode.OK) { JObject feed; resp.ResponsePayload.TryToJObject(out feed); var entities = JsonParserHelper.GetEntries(feed); if (null == entities || !entities.Any()) { detail.ErrorMessage = string.Format("Cannot find any entities from the entity-set '{0}'", entitySetName); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } bool isFirstLevelEmpty = false; int levelsCounter = 0; JObject entry = null; foreach (var en in entities) { levelsCounter = 0; entry = en as JObject; isFirstLevelEmpty = false; for (int i = 0; i < expectedLevels; i++) { if (entry != null && JTokenType.Object == entry.Type) { var navigPropVal = entry[navigPropNames[i]]; if (navigPropVal != null) { levelsCounter++; entry = navigPropVal.Type == JTokenType.Array ? navigPropVal.First as JObject : navigPropVal as JObject; if (entry == null) { isFirstLevelEmpty = true; break; } } } } if (expectedLevels == levelsCounter) { passed = true; } else if (!(levelsCounter < expectedLevels && isFirstLevelEmpty)) // If not no data { passed = false; detail.ErrorMessage = "The service does not execute an accurate result on the system query option '$levels' for expanded properties."; break; } } } else { passed = false; detail.ErrorMessage = "The service does not support the system query option '$levels' for expanded properties."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); 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; List <ExtensionRuleResultDetail> details = new List <ExtensionRuleResultDetail>(); ExtensionRuleResultDetail detail1 = new ExtensionRuleResultDetail(this.Name); ExtensionRuleResultDetail detail2 = new ExtensionRuleResultDetail(this.Name); var restrictions = new Dictionary <string, Tuple <List <NormalProperty>, List <NavigProperty> > >(); if (!AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities, ref restrictions)) { detail1.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } if (!AnnotationsHelper.IsSuitableNavigationProperty(NavigationRoughType.CollectionValued, ref restrictions)) { detail1.ErrorMessage = "Cannot find any collection-valued navigation properties in any entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } string entitySet = string.Empty; string navigPropName = string.Empty; #region Verify the system query $top. foreach (var r in restrictions) { if (string.IsNullOrEmpty(r.Key) || null == r.Value.Item1 || !r.Value.Item1.Any() || null == r.Value.Item2 || !r.Value.Item2.Any()) { continue; } foreach (var np in r.Value.Item2) { string nEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); string nEntitySetName = nEntityTypeShortName.MapEntityTypeShortNameToEntitySetName(); if (false == nEntitySetName.IsEntitySetSupportTopQuery(context.MetadataDocument, new List <string>() { context.VocCapabilities })) { continue; } navigPropName = np.NavigationPropertyName; break; } entitySet = r.Key; break; } if (string.IsNullOrEmpty(entitySet)) { detail1.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } if (string.IsNullOrEmpty(navigPropName)) { detail1.ErrorMessage = "Cannot find any collection-valued navigation properties which support system query options $top."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } bool? isTopQueryValidation = null; string url = string.Format("{0}/{1}?$expand={2}($top=1)", context.ServiceBaseUri, entitySet, navigPropName); var response = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail1 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), response); if (response.StatusCode == HttpStatusCode.OK) { JObject feed; response.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); foreach (var entity in entities) { if (entity[navigPropName] != null) { if (JTokenType.Array == entity[navigPropName].Type && ((JArray)entity[navigPropName]).Count <= 1) { isTopQueryValidation = true; } else { passed = false; detail1.ErrorMessage = "The service does not execute an accurate result on the system query option '$top' for expanded properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } } } } } else { passed = false; detail1.ErrorMessage = "The service does not support the system query option '$top' for expanded properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } #endregion #region Verify the system query $skip. foreach (var r in restrictions) { if (string.IsNullOrEmpty(r.Key) || null == r.Value.Item1 || !r.Value.Item1.Any() || null == r.Value.Item2 || !r.Value.Item2.Any()) { continue; } foreach (var np in r.Value.Item2) { string nEntityTypeShortName = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); string nEntitySetName = nEntityTypeShortName.MapEntityTypeShortNameToEntitySetName(); if (false == nEntitySetName.IsEntitySetSupportSkipQuery(context.MetadataDocument, new List <string>() { context.VocCapabilities })) { continue; } navigPropName = np.NavigationPropertyName; break; } entitySet = r.Key; break; } if (string.IsNullOrEmpty(entitySet)) { detail2.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } if (string.IsNullOrEmpty(navigPropName)) { detail2.ErrorMessage = "Cannot find any collection-valued navigation properties which support system query options $skip."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } bool?isSkipQueryValidation = null; url = string.Format("{0}/{1}?$expand={2}($skip=1)", context.ServiceBaseUri, entitySet, navigPropName); response = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail2 = new ExtensionRuleResultDetail(this.Name, url, "GET", StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders), response); if (response.StatusCode == HttpStatusCode.OK) { JObject feed; response.ResponsePayload.TryToJObject(out feed); if (feed != null && JTokenType.Object == feed.Type) { var entities = JsonParserHelper.GetEntries(feed); foreach (var entity in entities) { if (entity[navigPropName] != null) { int actualAmount = 0; JsonParserHelper.GetEntitiesNumFromCollectionValuedNavigProp(context.DestinationBasePath, (JObject)entity, navigPropName, context.RequestHeaders, ref actualAmount); if (JTokenType.Array == entity[navigPropName].Type && ((JArray)entity[navigPropName]).Count <= actualAmount)// TODO: This should be justified by total count { isSkipQueryValidation = true; } else { isSkipQueryValidation = false; detail2.ErrorMessage = "The service does not execute an accurate result on the system query option '$skip' for expanded properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(isSkipQueryValidation); } } } } } else { passed = false; detail2.ErrorMessage = "The service does not support the system query option '$skip' for expanded properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail1); return(passed); } #endregion if (isTopQueryValidation == true && isSkipQueryValidation == true) { passed = true; } details.Add(detail1); details.Add(detail2); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, details); 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); detail = info.Details[0]; List <string> supportedPropertyTypes = new List <string>(); #region Using ge and le as the single condition supportedPropertyTypes.Clear(); supportedPropertyTypes.AddRange(new List <string> { PrimitiveDataTypes.Int16, PrimitiveDataTypes.Int32, PrimitiveDataTypes.Int64, PrimitiveDataTypes.Decimal, PrimitiveDataTypes.Double }); var filterRestrictions = AnnotationsHelper.GetFilterRestrictionsWithoutNavi(context.MetadataDocument, context.VocCapabilities, supportedPropertyTypes); if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service."; } else { string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string primitivePropType = filterRestrictions.Item2.First().PropertyType; string url = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { passed = false; detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); } else { JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed == null || JTokenType.Object != feed.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option"; } else { var entities = JsonParserHelper.GetEntries(feed); Int64?propVal = null; for (int n = 0; n < entities.Count; n++) { //if (entities[0].Value != null) { try { propVal = entities[0].Value <Int64>(primitivePropName) - 1; break; } catch { } } } if (propVal == null) { detail.ErrorMessage = "Unable to find a suitable property to test. They have all returned NULL. Require a Int64 with data"; passed = false; return(passed); } //Int64 propVal = entities[0][primitivePropName].Value<Int64>(); string pattern = "{0}/{1}?$filter=not {2} eq {3}"; url = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail.URI = url; detail.HTTPMethod = "GET"; detail.RequestHeaders = StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders); detail.ResponseStatusCode = resp != null && resp.StatusCode.HasValue ? resp.StatusCode.Value.ToString() : ""; detail.ResponseHeaders = string.IsNullOrEmpty(resp.ResponseHeaders) ? "" : resp.ResponseHeaders; detail.ResponsePayload = string.IsNullOrEmpty(resp.ResponsePayload) ? "" : resp.ResponsePayload; if (resp.StatusCode != HttpStatusCode.OK) { passed = false; detail.ErrorMessage = "Request failed with system query option $filter not."; } else { JObject feed1; resp.ResponsePayload.TryToJObject(out feed1); if (feed1 == null || JTokenType.Object != feed1.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option $filter not."; } else { var entities1 = JsonParserHelper.GetEntries(feed1).ToList(); var temp = entities1.FindAll(en => (en[primitivePropName].Value <Int64>() == propVal)).Select(en => en); if (temp.Count() == 0) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter not."; } } } } } } #endregion Using ge and le as the single condition if (passed.HasValue && passed.Value) { return(passed); } #region Using startswith and endswith as the single condition supportedPropertyTypes.Clear(); supportedPropertyTypes.Add(PrimitiveDataTypes.String); filterRestrictions = AnnotationsHelper.GetFilterRestrictionsWithoutNavi(context.MetadataDocument, context.VocCapabilities, supportedPropertyTypes); if (string.IsNullOrEmpty(filterRestrictions.Item1) || null == filterRestrictions.Item2 || !filterRestrictions.Item2.Any()) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $filter system query options in the service."; } else { string entitySet = filterRestrictions.Item1; string primitivePropName = filterRestrictions.Item2.First().PropertyName; string primitivePropType = filterRestrictions.Item2.First().PropertyType; string url = string.Format("{0}/{1}", context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet); var resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail.URI = url; detail.ResponsePayload = resp.ResponsePayload; detail.ResponseHeaders = resp.ResponseHeaders; detail.HTTPMethod = "GET"; detail.ResponseStatusCode = resp.StatusCode.ToString(); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { passed = false; detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); } else { JObject feed; resp.ResponsePayload.TryToJObject(out feed); if (feed == null || JTokenType.Object != feed.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option"; } else { var entities = JsonParserHelper.GetEntries(feed); string propVal = entities[0][primitivePropName].Value <string>(); string pattern = "{0}/{1}?$filter=not endswith({2},'{3}')"; url = string.Format(pattern, context.ServiceBaseUri.OriginalString.TrimEnd('/'), entitySet, primitivePropName, propVal); resp = WebHelper.Get(new Uri(url), Constants.AcceptHeaderJson, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail.URI = url; detail.HTTPMethod = "GET"; detail.RequestHeaders = StringHelper.MergeHeaders(Constants.AcceptHeaderJson, context.RequestHeaders); detail.ResponseStatusCode = resp != null && resp.StatusCode.HasValue ? resp.StatusCode.Value.ToString() : ""; detail.ResponseHeaders = string.IsNullOrEmpty(resp.ResponseHeaders) ? "" : resp.ResponseHeaders; detail.ResponsePayload = string.IsNullOrEmpty(resp.ResponsePayload) ? "" : resp.ResponsePayload; if (resp.StatusCode != HttpStatusCode.OK) { passed = false; detail.ErrorMessage = "Request failed with system query option $filter not."; } else { JObject feed1; resp.ResponsePayload.TryToJObject(out feed1); if (feed1 == null || JTokenType.Object != feed1.Type) { passed = false; detail.ErrorMessage = "The service does not return a valid response for system query option $filter not."; } else { var entities1 = JsonParserHelper.GetEntries(feed1).ToList(); var temp = entities1.FindAll(en => en[primitivePropName].Value <string>().EndsWith(propVal)).Select(en => en); if (temp.Count() == 0) { passed = true; } else { passed = false; detail.ErrorMessage = "The service does not execute an accurate result with system query option $filter not."; } } } } } } #endregion Using ge and le as the single condition 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; ExtensionRuleResultDetail detail = new ExtensionRuleResultDetail(this.Name); var restrictions = new Dictionary <string, Tuple <List <NormalProperty>, List <NavigProperty> > >(); if (!AnnotationsHelper.GetExpandRestrictions(context.MetadataDocument, context.VocCapabilities, ref restrictions)) { detail.ErrorMessage = "Cannot find any appropriate entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (!AnnotationsHelper.IsSuitableNavigationProperty(NavigationRoughType.CollectionValued, ref restrictions)) { detail.ErrorMessage = "Cannot find any collection-valued navigation properties in any entity-sets which supports $expand system query options."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string entitySet = string.Empty; string navigPropName = string.Empty; string primitivePropertyName = string.Empty; foreach (var r in restrictions) { if (string.IsNullOrEmpty(r.Key) || null == r.Value.Item1 || !r.Value.Item1.Any() || null == r.Value.Item2 || !r.Value.Item2.Any()) { continue; } foreach (var np in r.Value.Item2) { string nEntityType = np.NavigationPropertyType.RemoveCollectionFlag().GetLastSegment(); var funcs = new List <Func <string, string, string, List <NormalProperty>, List <NavigProperty>, bool> >() { AnnotationsHelper.GetFilterRestrictions }; var expectedTypes = new List <string>() { "Edm.String" }; var props = MetadataHelper.GetNormalProperties(context.MetadataDocument, nEntityType); if (null == props || !props.Any()) { continue; } var targetProps = props.Where(p => expectedTypes.Contains(p.PropertyType)).Select(p => p); if (!targetProps.Any()) { continue; } navigPropName = np.NavigationPropertyName; primitivePropertyName = targetProps.First().PropertyName; break; } entitySet = r.Key; if (!string.IsNullOrEmpty(navigPropName) && !string.IsNullOrEmpty(primitivePropertyName)) { break; } } if (string.IsNullOrEmpty(entitySet)) { detail.ErrorMessage = "Cannot find an appropriate entity-set which supports $expand system query option."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (string.IsNullOrEmpty(navigPropName)) { detail.ErrorMessage = "Cannot get expanded entities because cannot get collection type of navigation property from metadata"; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } if (string.IsNullOrEmpty(primitivePropertyName)) { detail.ErrorMessage = "Cannot get an appropriate primitive property from navigation properties."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string url = string.Format("{0}/{1}?$expand={2}", context.ServiceBaseUri, entitySet, navigPropName); var resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (null == resp || HttpStatusCode.OK != resp.StatusCode) { detail.ErrorMessage = JsonParserHelper.GetErrorMessage(resp.ResponsePayload); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } JObject feed; resp.ResponsePayload.TryToJObject(out feed); var entities = JsonParserHelper.GetEntries(feed); if (null == entities || !entities.Any()) { detail.ErrorMessage = string.Format("Cannot find any entities from the entity-set '{0}'", entitySet); info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } string searchVal = string.Empty; foreach (var en in entities) { if (null != en[navigPropName] || JTokenType.Array == en[navigPropName].Type || en[navigPropName].Any()) { if (JTokenType.Object != en[navigPropName].First.Type) { break; } var nEntity = en[navigPropName].First as JObject; searchVal = nEntity[primitivePropertyName].ToString().Contains(" ") ? string.Format("\"{0}\"", nEntity[primitivePropertyName].ToString()) : nEntity[primitivePropertyName].ToString(); if (!string.IsNullOrEmpty(searchVal)) { break; } } } if (string.IsNullOrEmpty(searchVal)) { detail.ErrorMessage = "Cannot find any appropriate search values in the expanded entities."; info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); } url = string.Format("{0}/{1}?$expand={2}($search={3})", context.ServiceBaseUri, entitySet, navigPropName, searchVal); resp = WebHelper.Get(new Uri(url), Constants.V4AcceptHeaderJsonFullMetadata, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); detail = new ExtensionRuleResultDetail(this.Name, url, "GET", String.Empty, resp); if (null != resp && resp.StatusCode == HttpStatusCode.OK) { resp.ResponsePayload.TryToJObject(out feed); if (null != feed && JTokenType.Object == feed.Type) { entities = JsonParserHelper.GetEntries(feed); foreach (var e in entities) { var navigEntities = e[navigPropName].ToList(); if (null == navigEntities || !navigEntities.Any()) { continue; } foreach (var ne in navigEntities) { passed = null; if (searchVal.StripOffDoubleQuotes() == ne[primitivePropertyName].ToString()) { passed = true; } if (passed == null) { passed = false; detail.ErrorMessage = "The service does not execute an accurate result on the system query option '$search' for expanded properties."; } } if (passed == false) { break; } } if (null == passed) { detail.ErrorMessage = "Cannot find any appropriate data to verify this rule."; } } else { detail.ErrorMessage = "The service does not return an correct response payload."; } } else { passed = false; detail.ErrorMessage = "The service does not support the system query option '$search' for expanded properties."; } info = new ExtensionRuleViolationInfo(context.Destination, context.ResponsePayload, detail); return(passed); }