190 likes | 328 Views
RISSApps Implementation of GJXDM through Microsoft Visual Studio. RISSTech. RISSTech. Content Advisory!. This presentation is extremely technical, i.e., geeky to the core.
E N D
RISSApps Implementation of GJXDM through Microsoft Visual Studio RISSTech RISSTech
Content Advisory! • This presentation is extremely technical, i.e., geeky to the core. • Listening by non-geeks, or those geeks who do not program in the Microsoft Visual Studio .NET world, may cause drowsiness, head-nodding, and eye-glazing, and may impair your ability to drive or operate heavy machinery. • This presentation isn’t about best practices or standards, but how RISS has architected its applications. And please… Feel FREE to interrupt with questions!
Technical Architecture of RISSApps • Criminal Intelligence and Pointer Information system • Both a data repository and an exchange clearinghouse • SQL Server Database for data storage • .NET middleware (DLLs) • Multiple interfaces for user interaction and information exchange • Web/Windows application interfaces for users • Windows application for bulk upload of data • Data exchange interfaces • SQL Server interface • RISSDES web service (RDD/GJXDM 2 compliant) • RISSDES 2.0 web service (GJXDM 3 compliant) • Custom gateway interfaces to CSII and CISA
Technical Architecture of RISSApps – Middleware (Riss.dll) • Middleware provides single implementation for Officer, Subject, Organization, etc. • Purpose is to allow information to be used in a generic manner: • Interaction with user • Exchange to and from another system • Audit of internal and external user actions • Compliance with system-wide business rules • Allows code to be written that is applicable to all facets of the system
Technical Architecture of RISSApps – Web services (RISSDES 1 & 2) • Web service created for specific exchange • Web service consumes classes compatible with GJXDM implementation schema • Web service is simply a conversion from GJXDM classes to middleware classes and vice versa • Web service providing the conversion point allows exchange-specific information to be processed and passed to the middleware classes or returned as the result of the web service • Creating implicit operators will allow simpler programming: public static implicit operator GJXDMClass(BaseClass baseClass){…} allows you to in code do: BaseClass MyBaseClass; GJXDMClass MyClass = MyBaseClass;
Technical Architecture of RISSApps – Web services (RISSDES 1 & 2) • RISSDES 1 passes data as strings and is validated within code • RISSDES 2 uses strongly-typed classes, i.e., a PersonGivenName datatype is expected at the appropriate node within a Subject element • Strongly-typed version generates more specific WSDL, therefore is more useable as a web reference within Visual Studio .NET • String data provides much simpler WSDL, but requires more documentation and lacks automatic validation
Technical Architecture of RISSApps – Exchange mechanisms (Riss.DataExchange.[Specific].dll) • Specific exchanges done through implementation in its own DLL • Internal classes created to consume web service, i.e., Riss.DataExchange.GJXDM is the DLL frontend to RISSDES2 web service that is used by Riss.dll
Usage Example: User requests intel search data from external systems • Application accepts and validates user input, audits request, and creates base request object • Base request object creates exchange-specific objects for each queried system • Exchange-specific objects receive connection information (web service URL, database connection string, etc.) • Exchange-specific objects appropriately format IntelRequest • Exchange-specific objects request data from source • Exchange-specific objects receive responses • Base request object formats results for user
Usage Example: Intel search request from external system • Web service accepts and validates request from external system • Web service creates exchange-specific request object • Exchange-specific request object converted to base object • Base object asked to query data source • Source-specific object created with connection information • Source-specific object formats request for the source • Source-specific object requests data • Source-specific object returns data to base object • Base object passes data to exchange-specific request object • Web service returns XML generated from exchange-specific request object
Generating Classes from Schemas • Microsoft supplies xsd.exe with Visual Studio to create classes from schemas (among other things) • Due to proxying of code tables, some special considerations required to use xsd.exe on GJXDM subset schemas: • Doesn’t like relative directory references, i.e., ..\, in imported namespaces of the schema you are using • These references in <xsd:import> elements of the GJXDM schema need to be updated • It is OK to leave these in the proxy schemas, i.e., schemas in jxdm/3.0.x/proxy/<code source>/<version> subdirectories • Need to include all proxy, code source, subset, and implementation schemas in the command line
Generating Classes from Schemas • Pay attention to the help file for the xsd command! • Format for what we are needing to do: xsd <schema>.xsd /classes /e:<element> /n:<.NET namespace> • For example: xsd xsd.xsd usps_states\1.0\usps_states.xsd usps_states.xsd jxdm.xsd rissdes_2_0.xsd /c /e:SearchRequest /n:Riss.DataExchange.GJXDM would process the proxy schema and base schema for usps_states, jxdm (the subset schema), and rissdes_2_0 (the extension schema) and generate classes for the SearchRequest element in the Riss.DataExchange.GJXDM namespace
Creating Inherited Classes to work with GJXDM Data • Problem: • You want to use the ability of the xsd.exe tool to generate new classes when you update your specification • You need custom code attached to each class, and this will be overwritten when you re-run xsd.exe to generate new classes (i.e., implicit conversion operators!) • Solution: • Create classes that inherit your generated classes • Write your custom code within the inheriting class
Creating Inherited Classes to work with GJXDM Data public class DerivedContactInformationType : Riss.DataExchange.GJXDM.ContactInformationType { public void CustomMethod() { … } public static implicit operator… }
Dealing with XML Data: String or XML Document Object Model (DOM)? • String: • Faster than DOM • Not XML-aware • Good for sequentially building data string • Allows access to StringBuilder class, which is a substantially faster way to repeatedly append data to create a long string • DOM: • Allows access to node data (through XPath) without parsing • Good for building data out of order • Combination of the two is often effective: build parts as strings, convert those to an XML type, then append them to your XML type • Tweaking these has resulted in substantial code efficiency increases in RISSApps!
Serialization and Deserialization • Serialization is the process of turning an object into XML data • Deserialization is the process of turning XML data into an object • Good way to quickly convert from XML to classes and vice versa • Applies to the public members and properties of the class
Serialization • A method to create XML string data out of the object data: public string ToXml() { try { XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); MemoryStream stream = new MemoryStream(); serializer.Serialize(stream, this); System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string Output = encoding.GetString(stream.ToArray()); stream.Close(); return Output; } catch (Exception err) { throw new Exception("The XML string could not be created.\n" + err.Message); } }
Deserialization • A method to load XML data into the object public bool LoadFromXml(string preferenceXML) { try { XmlSerializer MySerializer = new XmlSerializer(typeof(MyClass)); System.Text.ASCIIEncoding myEncoding = new ASCIIEncoding(); byte[] myByteArray = myEncoding.GetBytes(preferenceXML); MemoryStream MyStream = new MemoryStream(myByteArray); MyClass MyObject = (MyClass)MySerializer.Deserialize(MyStream); return true; } catch //(Exception err) { return false; } }
Serialization and Deserialization • Serialization uses the class, member, or property name as the element name by default • Control of process possible through use of attributes placed before the class, such as [XmlArrayItem(“ElementArray”)] • XmlRoot renames and/or designates the top-level element of the XML • XmlIgnore causes the facet of the class to be skipped on serialization • XmlArray renames the XML element containing array • XmlArrayItem renames the individual XML elements within the array • XmlElement returns the array elements without a container
Thank You Carl Nelson Lead Developer Regional Information Sharing SystemsOffice of Information Technology Applications Development Group 545 Marriott Drive Suite 800 Nashville, Tennessee 37214 Telephone: 615.871.0013 cnelson@adg.riss.net