incubator-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Incubator Wiki] Update of "SynapseProposal/synapseobject" by VikasRoonwal
Date Wed, 22 Mar 2006 15:36:27 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Incubator Wiki" for change notification.

The following page has been changed by VikasRoonwal:
http://wiki.apache.org/incubator/SynapseProposal/synapseobject

New page:
= Synapse Object =

Hello everyone, this wiki gives an overview of what SynapseObject (also referred to as SO)
is all about, the reasons why it is being proposed. Changes suggested by Aleksander Slominski,
Mukund Balasubramanian and a few other have been incorporated too. 

== Introduction ==

Data representation has been a tough job always.  But with the advent of XML, representing
them has become much easier but still the data handling intelligence is missing. Say for instance
we have an XML 

== XML-1 ==

{{{
<contacts>
  <contact>
    <name>John</name>	
    <address>360 Morse Ave</address>
    <city>Sunnyvale</city>
    <state>US</state>
    <zip>94086</zip>
  </contact>
  <contact>
    <name>Mary</name>	
    <address>410 Dale Park</address>
    <city>Sunnyvale</city>
    <state>US</state>
    <zip>94086</zip>
  </contact>
</contacts> 
}}}

One can say that another way of representing them would be:

== XML-2 ==

{{{
<contacts>
  <contact name=”John” address=”360 Morse Ave” city=”Sunnyvale” state…></contact>
  <contact name=”Mary” address=”410 Dale Park” city=”Sunnyvale” state…></contact>
</contacts>
}}}

=== Differences Between XML 1 and XML 2 ===

>>From a generic standpoint both give the notion of a person’s address, XML-1 in this
context could be treated as more appropriate as it depicts that a contact has attributes in
the form of objects, where each composite object within has an identity of it’s own or each
of then can exists even if the contact object is not present but if you think deep, would
they meaningfully exist? Not really. At such a granular level it would become a nightmare
to maintain them, there could be two people with the same name.  
On the other hand XML-2 is more of a wysiwyg (What you see is what you get) but readability
wise maybe not be that great. 
There are different schools of thought in using XML but then XML has been conceived in a fashion,
which allows representation of data in any way users wish to put it. 
This of course gives immense control to the person who is writing it but then introduces a
whole lot of ambiguity when a different person gets it. The reason being the context is lost
in transmission.  At one end there is a whole lot of flexibility and on the other end ambiguity.

To resolve this issue, XSDs have been used to validate xmls from either end and provide some
control for type validation. Going forward Data-binding mechanisms have provided users to
produce classes/jars from an XSD and then using XMLs(conforming to the XSD) generate instances
that could be used for performing certain tasks. 
Take for instance XMLBeans from Apache, which generates java classes from a given XSD and
then allows you to get instances by passing an XML, which subscribes to the XSD format.

{{{
Note:
For the adventurous few, try out XMLBeans on the above 2 XMLs.
XML 1 - Leads to too many classes to handle
XML 2 - The code is quite cryptic
}}}

=== From a logical perspective (using XMLBeans) ===

1)	You need to generate classes (jars) from the XSD  

2)	After getting the xml (containing the data), generate instances of those classes

3)	Use the instances in some other container/Object to perform certain tasks.

Given the flexibility that the above approach gives one should be more than happy to use it.


''''' But consider the following '''''

== Problems with the above approach : ==

1)	You have to maintain the generated classes physically in some location

2)	Re-generate them in case the XSD changes

3)	Change the underlying logic in the classes which use the generated instances.

4)    No in-built search mechanism or features by which complex objects can be recursively
traversed to find embedded objects or attributes based on various criteria.


=== Alternate situation where ===

1)	No generation of classes are required

2)	No classes/jars to maintain

3)	Get instances directly from the XML based on the XSD

4)	Search feature to find attributes 

5)	Search feature to find embedded objects by giving attribute values

6)	Search feature to find embedded objects by giving attribute names

7)	And most importantly the object that you get from the XML is generic, so no need of casting
it. Just give the XML and get a generic object on which you can perform all the search features
as stated above and have the getters and setters too with type information!

 '''''This is what SynapseObject is all about. A utility object, that allows manipulation
and handling of XML in a generic fashion. '''''
== How does it work ==

It works in two modes

=== With an XSD ===

The constructor takes an XML and it’s corresponding XSD and spits out a SynapseObject instance

'''XML'''

{{{
<ConsumerIdentification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://somehost/SO-XML.xsd">
	<consumer>
		<CONSUMER_TYPE>GOLD</CONSUMER_TYPE>
		<IP_ADDRESS_FROM>192.167.6.0</IP_ADDRESS_FROM>
		<IP_ADDRESS_TO>192.168.6.255</IP_ADDRESS_TO>
		<HTTP_AUTH_USERNAME>john</HTTP_AUTH_USERNAME>
		<WS_SEC_USERNAME>john</WS_SEC_USERNAME>
		<assignedService>
			<serviceid>stockQuote1</serviceid>
		</assignedService>
	</consumer>
	<consumer>
		<CONSUMER_TYPE>SILVER</CONSUMER_TYPE>
		<IP_ADDRESS_FROM>192.167.8.0</IP_ADDRESS_FROM>
		<IP_ADDRESS_TO>192.168.8.255</IP_ADDRESS_TO>
		<HTTP_AUTH_USERNAME>Sam</HTTP_AUTH_USERNAME>
		<WS_SEC_USERNAME>Sam</WS_SEC_USERNAME>
		<assignedService>
			<serviceid>stockQuote1</serviceid>
		</assignedService>
	</consumer>
</ConsumerIdentification>
}}}

'''XSD'''

{{{
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
	<xs:element name="CONSUMER_TYPE">
		<xs:simpleType>
			<xs:restriction base="xs:string">
 		</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="ConsumerIdentification">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="consumer" maxOccurs="unbounded"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="HTTP_AUTH_USERNAME">
		<xs:simpleType>
			<xs:restriction base="xs:string">
		</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="IP_ADDRESS_FROM">
		<xs:simpleType>
			<xs:restriction base="xs:string">
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="IP_ADDRESS_TO">
		<xs:simpleType>
			<xs:restriction base="xs:string">
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="WS_SEC_USERNAME">
		<xs:simpleType>
			<xs:restriction base="xs:string">
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
	<xs:element name="assignedService">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="serviceid"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="consumer">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="CONSUMER_TYPE"/>
				<xs:element ref="IP_ADDRESS_FROM"/>
				<xs:element ref="IP_ADDRESS_TO"/>
				<xs:element ref="HTTP_AUTH_USERNAME"/>
				<xs:element ref="WS_SEC_USERNAME"/>
				<xs:element ref="assignedService"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="serviceid">
		<xs:simpleType>
			<xs:restriction base="xs:string">
			</xs:restriction>
		</xs:simpleType>
	</xs:element>
</xs:schema>
}}}

=== Without an XSD ===

The constructor takes an XMl and spits out a SynapseObject. The only dependency being the
XML should have the type definition for attributes in the XML itself.

'''XML for SynapseObject'''

{{{
<ConsumerIdentification>
 <consumer>
   <CONSUMER_TYPE type="STRING">GOLD</CONSUMER_TYPE>
   <IP_ADDRESS_FROM type="STRING">192.167.6.0</IP_ADDRESS_FROM>
   <IP_ADDRESS_TO type="STRING">192.168.6.255</IP_ADDRESS_TO>
   <HTTP_AUTH_USERNAME type="STRING">john</HTTP_AUTH_USERNAME>
   <WS_SEC_USERNAME type="STRING">john</WS_SEC_USERNAME>
   <assignedService>
    <serviceid1 type="STRING">stockQuote1</serviceid1>
   </assignedService>
 </consumer>
</ConsumerIdentification>
}}}

== Features ==

 * Create SynapseObject from SynapseObject-XML

 * Create SynapseObject from any xml by providing a xslt

 * SynapseObject can have a SynapseObject (self aggregation)

 * SynapseObject can have 0 or more attributes

 * To set attribute for a SynapseMediatorObject there are setters/getters methods such as
setString(String name,String value), setLong(String name,String value),etc. eg. SetString(foo,value)

 * SynapseObject has a getXMLFragment method which spits out an xml representing the SO itself.

 * SynapseObject have finder methods based on attribute names, values as well as SynapseObjects.

== CLASS-DIAGRAM : ==
[http://svn.apache.org/repos/asf/incubator/synapse/trunk/scratch/infravio/synapse-SO/SO-ClassDiag.JPG]

=== SynapseObject : ===

Synapse object is the core object, which follows the composite pattern. Each SynapseObject
can have one or more SynapseObject embedded within.  

=== Attribute handling : ===

The setters and getters are type based, example -> so.getString(“foo”) would spit out
a string for the attribute name foo. 

=== GenericObject : ===

For representing attributes a concept of holder object has been used which has the type, value
and name information of an attribute

=== SynapseObjectArray : ===

Represents an array of SynapseObjects.

=== Search Handling : ===

Search is based on
 
''Attribute name'' (also with added functionality like starts with or ends with) 
''Attribute value'' (also with added functionality like starts with or ends with)
''Object name'' (also with added functionality like starts with or ends with)

=== Translator : ===

Translate SynapeObject into any other format by passing a XSLT.

== Reasons for using SynapseObject ==

1) Java Properties class lets you handle name-value pairs in a very good way but when it comes
to representing complex objects it becomes very difficult.

2) Using the concept of data binding introduces a very rigid and tight coupling of data and
schema. So if the schema changes the underlying data handling mechanism needs to be changed
(which includes the beans/classes to hold the complex data structure)

3) Intelligent search features are either driven by xpath/xqueries for pure XML or embedded
logic if beans are used, SynapseObject has inbuilt search features by which you can perform
complex searches.

4) The reason people use Java Properties class is because name-value pairs can be shared by
other class without any dependency. SynapseObject is more like a Properties Class with added
features to handle Complex Objects and also allow search features.
 
== Uses Case ==

A) Data-Sharing between mediators: Consumers need to be identified, once it's identified the
information could be shared by the SLA mediator which depending on a consumer will set the
priority. Below is the pseudo code  of how this can be achieved using SynapseObject and how
datasharing would become easy.
 
''__Background Info__''

ConsumerIdentification mediator needs to identify a client by the following ways: 

1) IP {eg. 192.168.5.10} 

2) IP Range {eg. 192.168.5.20- 192.168.5.30} 

3) WS-SEC auth token 

4) HTTP auth token 

5) certificate
(Other factors that need to be considered whether the incoming message was first encrypted
and then signed or was it signed and then encrypted).

Let's consider 1) IP
 
== Using SynapseObject ==

{{{
ConsumerIdentification XML fragment:
------------------------------------
 
<?xml version='1.0' encoding='windows-1252'?>
		<Consumer_Identification>
                 <Consumer>
                   <CONSUMER_TYPE type=\"xsd:String\">GOLD</CONSUMER_TYPE>
                   <IP_ADDRESS_FROM type=\"xsd:String\">192.167.6.0</IP_ADDRESS_FROM>
                   <IP_ADDRESS_TO type=\"xsd:String\">192.168.6.255</IP_ADDRESS_TO>
                   <HTTP_AUTH_USERNAME type=\"xsd:String\">john</HTTP_AUTH_USERNAME>
                   <WS_SEC_USERNAME type=\"xsd:String\">john</WS_SEC_USERNAME>
                   <Assigned_Service>
                    <Service_ID type=\"xsd:String\">stockQuote1</Service_ID>
                   </Assigned_Service>
                 </Consumer>
                 <Consumer>
                   <CONSUMER_TYPE type=\"xsd:String\">SILVER</CONSUMER_TYPE>
                   <IP_ADDRESS_FROM type=\"xsd:String\">192.168.6.255</IP_ADDRESS_FROM>
                   <IP_ADDRESS_TO type=\"xsd:String\">192.168.6.255</IP_ADDRESS_TO>
                   <HTTP_AUTH_USERNAME type=\"xsd:String\">mary</HTTP_AUTH_USERNAME>
                   <WS_SEC_USERNAME type=\"xsd:String\">mary</WS_SEC_USERNAME>
                   <Assigned_Service>
                    <Service_ID type=\"xsd:String\">stockQuote1</Service_ID>
                   </Assigned_Service>
                 </Consumer>
                </Consumer_Identification>
}}}

In the ci mediator  code fragment

{{{ 
// the the requester ip 
ip = {get the remote ip from the messageContext/SynapseContext }
 
//Identify if the consumer is there and get appropriate details and store the consumer related
details in the messageContext, one more things to note is that storing shared data is by the
mediator name itself eg. ci 
SynapseObject obj = consumerIdentification.findSynapseObjectByAttributeValueStartingWith(ip);
messageContext.setProperty(consumerIdentification.getName(),obj);
obj will contain all the required values if identified!
}}}

{{{ 
SLA xml Fragment:
------------------
<sla>
    <consumer>
        < service>
            < epr type="String">http://www.webservicex.net/stockquote.asmx</epr>
            < priority type="Integer">0</priority>
        </service>
        < service>
            <epr type="String">http://www.webservicex.net/findZIPCode.asmx</epr>
            < priority type="Integer">1</priority>
        </service>
    </consumer>
</sla>
}}}
 
In the SLA Mediator code fragment

{{{ 
//As there is a dependency between the SLA mediator and CI the SLA mediator will pick information
for its dependency(Note: we also proposed a concept 
//of MediatorContext which will have dependency and other information for a particular mediator)
 
//Get the identified consumer from the messagecontext
SynapseObject consumerIdentification = (SynapseObject)messageContext.getProperty("ci");
 
// get the consumer name and consumer type
String consumerName = consumerIdentification.getName();
String consumerType = consumerIdentification.getString("CONSUMER_TYPE");
 
//find the sla details for the identified consumer
SynapseObject consumer = sla.findSynapseObjectByAttributeValue(consumerName);
String fromAddress = (String)synapseMessageContext.getTo();
SynapseObject service = consumer.findSynapseObjectByAttributeValue(fromAddress );
 
// The priority value would be used by the SLA mediator to forward the request to the provider
depending on the priority. 
String priority = service.getString("priority");
}}}

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@incubator.apache.org
For additional commands, e-mail: cvs-help@incubator.apache.org


Mime
View raw message