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 "Synapse/InProgress/RegistryAccessThoughts" by PaulFremantle
Date Mon, 03 Jul 2006 11:03:06 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 PaulFremantle:
http://wiki.apache.org/incubator/Synapse/InProgress/RegistryAccessThoughts

------------------------------------------------------------------------------
  
  We are trying to improve the way Synapse can load XML and configuration from more than just
synapse.xml.
  
- 1) Want to be able to pull config from more than one file.
+  1. Want to be able to pull config from more than one file.
- 2) Want to be able to name a source of one or more XMLs (a "registry"), and be able to easily
switch between say "test" and "production", and have many links change automatically
+  1. Want to be able to name a source of one or more XMLs (a "registry"), and be able to
easily switch between say "test" and "production", and have many links change automatically
- 3) Want to be able to have a "dynamic" config and re-read without restarting Synapse. Of
course we will implement caching to make sure its not really slow.
+  1. Want to be able to have a "dynamic" config and re-read without restarting Synapse. Of
course we will implement caching to make sure its not really slow.
  
- == Registry ==
+ == "Registry" ==
  
- Our first "registry" will just be a website. The 
+ Our first "registry" will just be a URL source like a webserver. The difference is that
you will specify a "root" URL prefix plus paths. Of course we'll make the registry interface
pluggable so that you can also deal with other real registries, or even UDDI :-)
  
+ == Using the model in synapse.xml ==
  
+ First pass design: 
  
- First pass design: There are exactly two registries defined. If we need more later we will
refactor.
+ We already have an internal naming system in Synapse, which is a hashtable bootstrapped
by the '''definitions''' section. 
+ We can think of this as an in-memory registry. We can then back this up with an external
registry, so if you don't find something in the memory one, you look it up in the external
registry. We thought about having multiple registries, but figured a good starting point was
just one external registry, and if we need more later we can add support then.
  
- The core "in-memory" Registry is basically defined by a hashtable. If something is not found
there then Synapse automatically looks up the key in the other registry. The other registry
is defined by an interface and you can configure the provider using the following XML syntax:
+ The external registry is defined by an interface and you can configure the provider using
the following XML syntax:
+ 
+ {{{
+ <syn:registry provider="provider.class">
+   <property name="prop-for-Registry" value="...">
+ </syn:registry>
+ }}}
+ 
+ Our first URL based HTTP registry will look like this:
  
  {{{
  <syn:registry provider="o.a.s.r.HTTPRegistry">
-   <property name="prop-for-HTTPRegistry" value="...">
+   <property name="root" value="http://localhost:80/myxmls">
  </syn:registry>
  }}}
+ 
  
  At the moment the properties in our config 
  {{{
@@ -33, +45 @@

   1. only strings
   1. only loaded from this XML (i.e. not pulling in an external resource)
  
- This proposes changing this. Instead of having each mediator pull XML config or metadata
in its own way, we can extend the properties to support XML, and then have the mediators grab
the XML from the "in-memory" registry. This means that we could remove any "src" tags from
mediators and have mediators use a common pattern to access external xml. However, we will
still expect mediators to allow inline XML "right there" so as to make the structure easy
and clear. So an XSLT can be loaded from a file, in which case its specified at the top using
a property; or inlined, when it can be either in a property or in the actual <xslt/>
element.
+ We will change this:
+ 
+ Instead of having each mediator pull XML config or metadata in its own way, we can extend
the properties to support XML, and then have the mediators grab the XML from a property. The
property can either be in memory or a key to the external registry.
+ 
+ So in effect we will funnel any access to external XMLs through the "registry" model. 
+ We will remove any "src" tags from mediators and instead have them reference XML through
the property / registry model. 
+ 
+ However, we will still expect mediators to allow inline XML "right there" so as to make
the structure easy and clear. So an XSLT can be loaded from a file, in which case its specified
at the top using a property; or inlined, when it can be either in a property or in the actual
<xslt/> element.
  
  {{{
  mediator <== property <== (value | inline | src | lookup)
@@ -47, +66 @@

   </property>
  }}}
  
- Note that the particular approach of '''<property name="" key=""/>''' is really just
an aliasing mechanism.
+ Note that the particular approach of '''<property name="" key=""/>''' is really just
an aliasing mechanism - its setting up a link between an internal key and an external key
into the external registry. And if you specify a '''key''' then it will lookup the entry *whenever*
you use it. Of course we will optimize cache etc this. 
  
- If you specify a key then it will lookup the entry *whenever* you use it. Of course we will
optimize cache etc this. But the semantic is dynamic.
+ So now if I specify
+ {{{
+  <property name="stockxsl" key="/xsls/stockquote.xsl"/>
+ }}}
  
- We also want to be efficient at converting these XMLs into config objects. For example,
Spring configs need to be built into application contexts, XSLTs compiled, etc.
+ Then together with the registry definition above, this will load the XSL from http://localhost:80/myxmls/xsls/stockquote.xsl
and associate it with the local name '''stockxsl'''. 
  
+ I can now use this xsl like this:
+ 
+ <transform xslt="stockxsl"/>
+ 
+ This will be dynamic, so if I update the file at http://localhost:80/myxmls/xsls/stockquote.xsl
it will be picked up and used by Synapse without restarting.
+ 
+ == Internal Registry API ==
+ 
+ The core in-memory registry is actually the SynapseEnvironment properties model. The other
registry is just a mapping from keys (strings) to XML fragments (OMNode).  
+ 
+ {{{
+ SynapseEnvironment {
+    ...
+    Object getProperty(String name);
+    ...
+    XMLRegistry getXMLRegistry();
+    ...
+ }
+ }}}
+ 
+ {{{
+ public interface XMLRegistry {
+   OMNode lookup (String key);
+   OMNode lookupIfModified (String key, long since);
+   void insert (key, OMNode);
+ }
+ }}}
+ 
+ 
+ == Efficiency ==
+ 
+ We tried to get the "user model" right first, so now we'd like to make sure its efficient.

+ 
+ In order to make this model efficient, we need to be able to cache objects: Imagine you
have an XSLT that you are looking up from the registry. You want to be able to compile the
XSLT only once. When someone asks for it again, you want to check if its been modified, and
only recompile if it has. 
+ 
+ So there are two efficiencies involved here:
+  1. Fetching the XSL from the URL. Make sure we use GetIfModified etc, and maybe set a timer
locally so we don't even check IfModified if I checked in the last n seconds.
+  1. Compiling the XSLT - if the XML/XSLT code hasn't changed we shouldn't recompile it.
+ 
+ Internally we figured we could handle the first by having the "lookupIfModified" method
on the registry provider API.
+ 
- So we will maintain a list of "converters" which can convert from the XML to an object.
If a given converter is registered, then we always run it on the XML before returning the
property. So here is the pseudo-code for getProperty
+ For the second aspect we will maintain a list of "converters" which can convert from the
XML to an object. If a given converter is registered, then we always run it on the XML before
returning the property. So here is the pseudo-code for getProperty
  
  {{{
  public class DynamicProperty {
@@ -62, +125 @@

     long timeCached;
     String key;
  }
-     
-    
  
  SynapseEnvironment.getProperty(String key) {
      Object obj = hashtable.lookup(key);
@@ -86, +147 @@

      }
      return obj;
  }
+ 
+ SynapseEnvironment.registerMapper(String key, Mapper mapper);
- }}}
- The actual pseudo code we typed was: 
- {{{
- 0. registry.lookupIfModified
- 1. try lookup in hash as property
- 2. fails, now lookupRegistry
- 3. XML -> Object
- 4. Stick in hash under name
- 5. next time hits on #1
  }}}
  
- The core in-memory registry is actually the SynapseEnvironment properties model. The other
registry is just a mapping from keys (strings) to XML fragments (OMNode).  
+ So the XSL mediator can register its compiler with the DynamicObject 
  
- {{{
- SynapseEnvironment {
-    ...
-    Object getProperty(String name);
-    ...
-    XMLRegistry getXMLRegistry();
-    ...
- }
- }}}
- 
- {{{
- public interface XMLRegistry {
-   OMNode lookup (String key);
-   OMNode lookupIfModified (String key, long since);
-   void insert (key, OMNode);
- }
- }}}
- 
- In order to make this model efficient, we need to be able to cache objects: Imagine you
have an XSLT that you are looking up from the registry. You want to be able to compile the
XSLT only once. When someone asks for it again, you want to check if its been modified, and
only recompile if it has. 
- 
- We haven't yet fully solved this (because we concentrated on the external view) but at least
Paul thinks there is a neater way than the current extension definition approach. The idea
revolves around a given mediator passing over a "XMLtoObjectMapper" back to the SynapseEnvironment
with a given property. Then the property lookup can check if the XML has changed, and only
then rerun the compilation/conversion step.
- 

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


Mime
View raw message