This project is read-only.

This document describes how to add new rule to the validation tool. You can visit the rule service at [place holder] to see which rules are available and which rules are under development.

General speaking, there are two types of rules: Structural and Semantic. An example of the Structural rule would be that there should be only one Workspace element in the service document. An example of the Semantic rule would be that system query option $top = 2 should return only 2 entries.

There are two ways to implement the rules: XML based and Code based. In general, XML based implementation is ideal for Structural rules where Code based is ideal for Semantic rules. However, there is no hard requirement on for implementing rules. You can certainly use Code Based implementation for Structural rules and vice versa.

Authoring XML Rules

This section describes how to author rules using XML based implementation.

Processing Flow

clip_image002

Note: The rule will undergoing macro replacement and XSLT transformation before validating the payload against the schema if specified in the Action Processor attribute.

Rule Structure

This section describes the rule skeleton. A XML based rule looks like the following:

<rules>

<rule id="SvcDoc.Core.1000" category="core" target="servicedoc" specificationsection ="2.2.6.2.7" requirementlevel="should" format="xml">

<description>The root URL of a data service that implements the AtomPub protocol SHOULD identify the service document.</description>

<action processor="rng">

<!- Validation Schema is placed here -/>

</action>

</rule>

</rules>

Header

The below table shows the attributes in the header:

Attribute Name

Value

Note

id

Must be unique

 

category

core, query, formoverdata, and lineofbusiness

 

target

servicedoc, metadata, feed, and entry

This attribute specifies the payload target to run the rules against with.

specificationsection

Section number in the Protocol specification

 

requirementlevel

Must, mustnot, should, shouldnot, and may

 

format

xml, atompub, and json

This attribute specifies the payload format.

metadata

true or false

Must set to true if the rule contains XSLT code.

mle

true or false

Default is false

aspect

structural and semantic

Default is structural

Description

This element contains the description for the rule, typically extracted from the protocol specification.

Action

This element specifies how and what to validate. The below table shows a list of the processor type:

Type

Action

Example

rng

Perform RelaxNG schema validation against the payload

Feed.Core.1000.xml

xslt+rng

Transform the rule and then perform RelaxNG schema validation against the payload

Entry.Core.1003.xml

jsonschema

Perform JSON schema validation against the payload

Common.Core.1002.xml

xslt+jsonschema

Transform the rule and then perform JSON schema validation against the payload

Entry.Core.1025.xml

headerregex

Perform regular expression match on the Http Header

SvcDoc.Core.1006.xml

regex

Perform regular expression match on the payload

Feed.Core.1003.xml

For more information regarding Relax NG Schema and JSON Schema, see http://www.relaxng.org/ and http://json-schema.org/ respectively.

ErrorMessage

This is currently not in use.

Macro

The below table shows the macro used in rule engine:

Macro Name

Description

Example

$ENTITYTYPE$

Entity Type. For example, Category.

Entry.Core.1003.xml

$NSENTITYTYPE$

Entity Type with full namespace. For example, NorthwindModel.Category.

Entry.Core.1008.xml

$URI$

Input URI

Feed.Core.1001.xml

$LSURI$

The last segment of the input URI

Entry.Core.1010.xml

Create and Deploy XML Based Rule

Create a XML file, set the attributes in the header, and implement the action. To deploy the XML based rules, simply copy the XML files to the C:\ValidationTool\ODataValidationService\ODataValidationService\rulestore folder and then restart the IIS service to pick up the changes. Under tool directory, there is a rule builder sample for your reference.

Validating XML Rules

You can verify your implementation without deploying them to the validation tool. To do so,

1. Transform the rule using the online tool at http://www.shell-tools.net/index.php?op=xslt. Copy and paste the rule in to the xslt textbox and metadata document into the xml textbox. Before you copy and paste the rule, if you’re using macro, you need to replace them with value corresponding to the metadata document.

2. Create a console project and verify the payload against the RelaxNG schema or JSON schema using the code snippet in below.

RelaxNG Schema

Copy and paste the following into a console project,

class Program

{

static void Main(string[] args)

{

if (args.Length == 0)

{

Help();

return;

}

RelaxngPattern schema = null;

// set up Relax NG schema

string jsonSchemaPath = args[0];

using(var textReader = File.OpenText(jsonSchemaPath))

using (XmlTextReader xtrRng = new XmlTextReader(textReader))

{

try

{

schema = RelaxngPattern.Read(xtrRng);

schema.Compile();

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

// validate xml payloads aginst the Relax NG schema

if (args.Length == 1)

{

TextReader rdr = Console.In;

Validate(schema, rdr);

}

else

{

foreach (var path in args.Skip(1))

{

TextReader rdr = File.OpenText(path);

Validate(schema, rdr);

}

}

}

static void Validate(RelaxngPattern schema, TextReader xml)

{

using (XmlTextReader xtrXml = new XmlTextReader(xml))

using (RelaxngValidatingReader vr = new RelaxngValidatingReader(xtrXml, schema))

{

try

{

while (!vr.EOF)

{

vr.Read();

}

}

catch (RelaxngException rngex)

{

Console.WriteLine(rngex.Message);

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

}

static void Help()

{

Console.WriteLine(

@"

To validate xml literals with Relax NG schema.

Synopsis:

rngValidator <path-RngSchema> <path-xml-literal>+

rngValidator <path-RngSchema>

");

}

}

JSON Schema

Copy and paste the following into a console project,

class Program

{

static void Main(string[] args)

{

if (args.Length == 0)

{

Help();

return;

}

string jsonSchemaPath = args[0];

string jsonSchemaText = File.ReadAllText(jsonSchemaPath);

JsonSchema jsonSchema = JsonSchema.Parse(jsonSchemaText);

if (args.Length == 1)

{

TextReader rdr = Console.In;

Validate(jsonSchema, rdr);

}

else

{

foreach (var path in args.Skip(1))

{

TextReader rdr = File.OpenText(path);

Validate(jsonSchema, rdr);

}

}

}

private static void Validate(JsonSchema jsonSchema, TextReader rdr)

{

using (JsonTextReader jdr = new JsonTextReader(rdr))

using (JsonValidatingReader vr = new JsonValidatingReader(jdr))

{

vr.Schema = jsonSchema;

try

{

while (vr.Read()) { };

}

catch (JsonSchemaException jex)

{

Console.WriteLine("line {0}, col {1} : {2}", jex.LineNumber, jex.LinePosition, jex.Message);

}

}

}

static void Help()

{

Console.WriteLine(

@"

To validate json literals with Json schema.

Synopsis:

jsonValidator <path-jsonSchema> <path-json-literal>+

jsonValidator <path-jsonSchema>

");

}

}

Authoring Code Rules

This section describes how to author Code based rules. The validation tool has an extension for implementing the Code based rules. The extension is leveraging the Managed Extensibility Framework (MEF). Similar to the XML based rule, the header attributes are now the properties in the class and the action is now Verify method shown in below:

public override bool Verify(ServiceContext context, out ExtensionRuleiolationInfo info)

Under tool directory, there is a rule builder sample for your reference.

Step 1: Add a New Class Library Project

Add a new project and then add the below references:

· System.ComponentModel.Composition

· ODataValidator.RuleEngine

Step 2: Implement the Rule

Add a new class file and then implement the rule. See CommonCore1000.cs for example.

Step 3: Deploy Code Based Rule

Compile the project and then copy the assembly to C:\ValidationTool\ODataValidationService\ODataValidationService\extensions folder and then restart the IIS service to pick up the changes.

Validating Code Rules

You can verify your implementation without deploying them to the validation tool. To do so, copy and paste the following code in to a console application project,

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ODataValidator.RuleEngine;

namespace ODataSpecValidate

{

class SimpleResultConsumer : IResultProvider, ILogger

{

public void Accept(TestResult result)

{

Console.WriteLine("{0}:{1}:{2}:{3}",

result.RuleName,

result.Classification,

result.ErrorDetail,

result.Description

);

}

public void JobCompleted(bool errorOccurred)

{

}

public void Log(RuntimeException runtimeError)

{

}

}

class Program

{

static void Main(string[] args)

{

if (args.Length < 2)

{

Console.WriteLine("Usgae: ODataSpecValidate <odata-endpoint> <atompub|json>");

return;

}

string destination = args[0];

string format = args[1];

var logger = new SimpleResultConsumer();

// populates all the rules - particulay from semantic extension assemblies

var store0 = new RuleStoreAsXmlFolder("rulestore", logger);

foreach(var rule in store0.GetRules())

{

if (rule.IsValid())

{

RuleCatalogCollection.Instance.Add(rule);

}

}

var store1 = new ExtensionRuleStore("extensions", logger);

foreach (var rule in store1.GetRules())

{

if (rule.IsValid())

{

RuleCatalogCollection.Instance.Add(rule);

}

}

// establishes the servce context

Guid jobId = Guid.NewGuid();

var context = ServiceContextFactory.Create(destination, format, jobId, 1024 * 1024);

// sets up rule engine

var facade = new RuleEngineWrapper(context, logger, logger);

facade.Validate();

}

}

}

Last edited Nov 3, 2011 at 1:20 AM by jcyang75, version 2

Comments

No comments yet.