 |
|
<<O>> Difference Topic
ExtConfig
(21 - 12 Jun 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease
Table of Contents | | |
--> | |
> > |
Next Steps
ed: placeholder for ext.next topics
| | |
Resources |
|
<<O>> Difference Topic
ExtConfig
(20 - 24 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease
Table of Contents | | | try {
AbstractConfigurator? c = new AbstractConfigurator?(new URI(...), new Profile(...)) {
... | |
< < | }.configure(); | > > | }; | | | npg = NetPeerGroupFactory?(c.configure(), c.getJxtaHome()); |
|
<<O>> Difference Topic
ExtConfig
(19 - 23 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease
Table of Contents | | |
- Profile
- alternative backing Configurator delegate
| |
< < | Typical usage is to override the defaults by specifying an application specific working directory (aka JXTA HOME) and application specific Profile. Following is such an example with the addition of a work we will address shortly: | > > | Typical usage is to override the defaults by specifying an application specific working directory (aka JXTA HOME) and application specific Profile. Following is such an example with the addition of a Profile, which we will address shortly: | | |
... | | | } catch(ConfigurationException? ce) {
...
} catch (PeerGroupException? pge) { | |
> > | ... | | |
| | | throws ConfiguratorException?
| |
< < | As as application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data to the running JXTA instance. | > > | As an application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data to the running JXTA instance. | | |
... | | | }
| |
< < | Alas, life is typically not so simple and as such we move on to explore a the available Configurator modifier methods. Before doing so, let's align with the afore mentioned AbstractConfigurator code sample by overriding the default constructor with an alternative working directory and profile, as follows: | > > | Alas, life is typically not so simple and as such we move on to explore the available Configurator modifier methods. Before doing so, let's align with the afore mentioned AbstractConfigurator code sample by overriding the default constructor with an alternative working directory and profile, as follows: | | |
... | | |
- endpoint [local resource configuration]
- miscellaneous [e.g. configuration and extensions]
| |
< < | At this time we'll expand on some key members within the configuration family noting that all modifiers are listed shortly along with a brief description. | > > | At this time we'll expand on some key members within the configuration family noting that all Configurator modifiers are listed shortly along with a brief description. | | | Peer information including name, working directory, certificate, and logging information can be specified as follows: | | | An abstract BaseOptimizer can be implemented easing the manufacturing of specialized optimizers, e.g.: | |
> > | ... | | | import net.jxta.ext.config.optimzers.BaseOptimizer;
... | | | ...
| |
< < | While Configurator includes several methods, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining modifiers of specific interest. | > > | While Configurator includes several methods, common practice is to instantiate a Configurator from a baseline Profile and only invoke the few remaining modifiers that are of specific interest. | | | Now that we have a desired configuration state the next step is to generate the representative PlatformConfig object, which is done by inoking the getPlatformConfig() method: | | | Lastly, the resulting configuration state is applied against a series of internal integrity constraints assuring configuration viability and possibly throwing a ConfiguratorException that is comprised of a chained list of all validation valure root causes. | |
< < | Lastly, one can optionally persist the derived configuration artifacts by invoking the save() method. save() invokes the getPlatformConfig() method in the event is has not been previously invoked. | > > | Before disposing of the Configurator instance, one can optionally persist the derived configuration artifacts by invoking the save() method. save() invokes the getPlatformConfig() method in the event is has not been previously invoked. | | |
Profile (aka ext:config/profile) | |
< < | A Profile is a declarative means to manage Configurator instantiation and state via composable presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. A series of common configuration presets accessible as static members of the Profile class. Further, one can construct an application specific profile in order to manage specialized configuration requirements. | > > | A Profile is a declarative means to manage Configurator instantiation and state via composable presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. A series of common configuration presets accessible as static members of the Profile class. Further, one can construct an application specific profile in order to manage specialized configuration requirements. | | | | |
< < | All profile addresses are specified as URIs. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Further, partial addresses will be resolved against a backing contextual template. | > > | All profile addresses are specified as URIs. Addresses that do not specify scheme information will be defaulted according to the respective context. Further, partial addresses will be resolved against a backing contextual template. | | | | |
< < | All fields have backing defaults enabling one to specify only the required overrides in order to construct complete configuration profiles. | > > | All fields have backing defaults enabling one to specify only the required overrides in order to efficiently construct complete configuration profiles. | | | The principal ext:config/profile class is: | | | Profile p = null;
try { | |
< < | p = new Profile(new URI("file:./profile.xml")); | > > | p = new Profile(new URI("file:./myprofile.xml")); | | | } catch (MalformedURLException mue) {
...
} catch (URISyntaxException? use) { | | |
...
| |
< < | // p = new Profile(new URI("file:./profile.xml"));
p = new Profile(getClass().getResourceAsStream("/path/to/my/profile.xml")); | > > | // p = new Profile(new URI("file:./myprofile.xml"));
p = new Profile(getClass().getResourceAsStream("/path/to/myprofile.xml")); | | | ...
| | |
- /jxta [jxta configuration]
- /peer [peer, application and working environment information]
- @name [peer name (e.g. "myPeer")]
| |
> > |
-
-
- @id [peer id (e.g. "urn:jxta:uuid-59616261646162614A78746150325033D186291E80AB4CD1875F8FF5C2CE2F9503)"]
| | |
-
-
- @descriptor [peer description, (e.g. "me myself i")]
| |
< < |
-
-
- @id [peer id (e.g. urn:jxta:uuid-59616261646162614A78746150325033D186291E80AB4CD1875F8FF5C2CE2F9503)]
| | |
-
-
- @home [working directory (e.g. "file:./myjxta")]
- @trace [log level (e.g. "debug")]
- /description [peer description (e.g. "long version of me myself i")]
| | |
-
-
-
- @enabled [?security activation? (e.g. "true")]
- @principal [credential principal (e.g. "me")]
- /rootCert [root certificate (e.g. "MIICEDCCAXmgAwIBA...")]
| |
< < |
-
-
-
- @address [root certificate address (e.g. "file:./me.cer")]
| > > |
-
-
-
- @address [root certificate address (e.g. "file:./mycert.pem")]
| | |
-
-
- /proxy [http proxy (e.g. "http://[usr:pwd@]proxy.org[:port]")]
- @enabled [http proxy activation (e.g. "true")]
- /network [jxta network resources including network, rendezVous and relays]
| |
< < |
-
-
- @id [net peer group id (e.g. "urn:jxta:uuid-5702345907204359072934759073490702")]
| > > |
-
-
- @id [net peer group id (e.g. "urn:jxta:uuid-59616261646162...E2F9503")]
| | |
-
-
- @name [net peer group name (e.g. "MyNet")]
- @description [net peer group description (e.g. "me myself i network")]
- /rendezVous [seeding rendezVous]
| | |
-
-
-
-
- @enabled [server activation (e.g. "true")]
- /outgoing [client]
- @enabled [client activation (e.g. "true")]
| |
< < |
-
-
-
- /address [ipv6 or ipv4 tcp address (e.g. "tcp://1.2.3.4:9701")]
- @range [upper bound port range (e.g. 100)]
- /multicast [multicast (e.g. "udp://224.0.1.85:1234")]
| > > |
-
-
-
- /address [physical tcp address (e.g. "tcp://1.2.3.4:9701")]
- @range [port range (e.g. "100")]
- /multicast [multicast address (e.g. "udp://224.0.1.85:1234")]
| | |
-
-
-
-
-
- @enable [multicast activation (e.g. "false")]
- @size [multicat packet size (e.g. "16338")]
| |
< < |
-
-
-
- /publicAddress [public address (e.g. "tcp://5.6.7.8:9701"]
- @exclusive [don't publish tcp address (e.g. "false")]
- /proxy [tcp proxy (e.g. "tcp://5.6.7.8:8080")]
| > > |
-
-
-
- /publicAddress [publicly addressable address (e.g. "tcp://5.6.7.8:9701")]
- @exclusive [don't publish physical tcp address (e.g. "false")]
- /proxy [tcp proxy address (e.g. "tcp://5.6.7.8:8080")]
| | |
-
-
-
-
- @enabled [proxy activation (e.g. "false")]
- /http [http address(es)]
- @enabled [http transport activation (e.g. "true")]
| | |
-
-
-
-
- @enabled [server activation (e.g. "false")]
- /outgoing [client]
- @enabled [client activation (e.g. "true")]
| |
< < |
-
-
-
- /address [[ipv6 or ipv4 tcp address ("http://1.2.3.4:9700")]
- @range [upper bound port range (e.g. "100")]
- /publicAddress [public address (e.g. "http://5.6.8.9:9700")]
- @exclusive [don't publish http address (e.g. "false")]
- /proxy [http proxy (e.g. "http://5.6.7.8:8080")]
| > > |
-
-
-
- /address [physical http address ("http://1.2.3.4:9700")]
- @range [port range (e.g. "100")]
- /publicAddress [publicly addressable address (e.g. "http://5.6.8.9:9700")]
- @exclusive [don't publish physical http address (e.g. "false")]
- /proxy [http proxy address (e.g. "http://5.6.7.8:8080")]
| | |
-
-
-
-
- @enabled [proxy activation (e.g. "false")]
- /service [provisioned services]
- /rendezVous [rendezVous service]
- @enabled [rendezVous activation (e.g. "false")]
| |
< < |
-
-
-
- /autoStart [auto rendezVous (e.g. "120000")]
| > > |
-
-
-
- /autoStart [start rendezVous if unable to establish a lease after specified milliseconds (e.g. "120000")]
| | |
-
-
-
-
- @enabled [auto rendezVous activation (e.g. "false")]
- /relay [relay service]
- @enabled [relay activation (e.g. "false")]
| | | ...
Configurator c = new Configurator(Profile.EDGE); | |
> > | // Configurator c = new Configurator(Profile.SUPER); | | |
A specialized Profile can be readily used as follows: |
|
<<O>> Difference Topic
ExtConfig
(18 - 22 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease
Table of Contents | | | PeerGroup npg = null;
// xxx: specifying a System property for JXTA_HOME will no longer be required in future releases | |
< < | System.setProperty("JXTA_HOME", new File(home).getAbsolutePath()); | > > | System.setProperty("JXTA_HOME", new File("myHome").getAbsolutePath()); | | | try {
new AbstractConfigurator?() { |
|
<<O>> Difference Topic
ExtConfig
(17 - 22 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease
Table of Contents | | |
- net.jxta.ext.config.ui.Configurator
| |
< < | (ed: wip) | > > | status: work in progress | | |
Just Code |
|
<<O>> Difference Topic
ExtConfig
(16 - 22 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease | |
< < | | | | Table of Contents | | | public class MyConfigurator?
extends AbstractConfigurator? { | |
> > | private static final String NAME = "name";
private static final String PRINCIPAL = "principal";
private static final String PASSWORD = "password"; | | | public PlatformConfig createPlatformConfig(Configurator c)
throws ConfiguratorException? { | |
< < | c.setName("name");
c.setSecurity("principal", "password"); | > > | c.setName(NAME);
c.setSecurity(PRINCIPAL, PASSWORD); | | | return c.getPlatformConfig();
} | | | import net.jxta.peergroup.PeerGroupFactory;
... | |
< < | AbstractConfigurator? c = new AbstractConfigurator?() { | > > | private static final String NAME = "name";
private static final String PRINCIPAL = "principal";
private static final String PASSWORD = "password";
...
PeerGroup npg = null;
// xxx: specifying a System property for JXTA_HOME will no longer be required in future releases
System.setProperty("JXTA_HOME", new File(home).getAbsolutePath());
try {
new AbstractConfigurator?() { | | | public PlatformConfig createPlatformConfig(Configurator c)
throws ConfiguratorException? { | |
< < | c.setName("name");
c.setSecurity("principal", "password"); | > > | c.setName(NAME);
c.setSecurity(PRINCIPAL, PASSWORD); | | | return c.getPlatformConfig();
} | |
< < | }
PeerGroup npg = null;
try {
c.configure(); | > > | }.configure(); | | | npg = PeerGroupFactory?.newNetPeerGroup(...);
} catch(ConfigurationException? ce) { | | | } catch (PeerGroupException? pge) {
...
} | |
> > | ... | | |
The above code will perform the following actions: | | |
- Profile
- alternative backing Configurator delegate
| |
< < | Typical usage is to override the defaults by specifying an application specific working home (aka JXTA HOME) and application specific Profile. Following is such an example with the addition of a work we will address shortly: | > > | Typical usage is to override the defaults by specifying an application specific working directory (aka JXTA HOME) and application specific Profile. Following is such an example with the addition of a work we will address shortly: | | |
... | | | import java.net.URI;
... | |
< < | URI home = new URI(...);
// xxx: specifying a System property for JXTA_HOME is not required in future releases
System.setProperty("JXTA_HOME", new File(home).getAbsolutePath());
Profile profile = new Profile(...);
AbstractConfigurator? c = new AbstractConfigurator?(home, profile) { | > > | try {
new AbstractConfigurator?(new URI(...), new Profile(...)) {
...
}.configure();
npg = PeerGroupFactory?.newNetPeerGroup(...);
} catch(URISyntaxException? use) {
...
} catch(ConfigurationException? ce) {
...
} catch (PeerGroupException? pge) {
... | | |
In addition to the above mentioned processes, the above code will: | | | Barring exceptions, one can then instantiate a JXTA Platform by referencing the derived JXTA Home and it's included artifacts, namely PlatformConfig.
| |
< < | A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently configure and start a peer instance in addition to optionally persisting the configuration artifacts (see commons/modules/ext): | > > | A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently and fully configure and subsequently start a peer instance in addition to optionally persisting the configuration artifacts (see commons/modules/ext): | | |
... | |
< < | //import net.jxta.peergroup.PeerGroupFactory; | | | import net.jxta.peergroup.NetPeerGroupFactory;
... | |
< < | | | | try { | |
< < | // c.confgure();
//
// npg = PeerGroupFactory?.newNetPeerGroup(...); | > > | AbstractConfigurator? c = new AbstractConfigurator?(new URI(...), new Profile(...)) {
...
}.configure(); | | | npg = NetPeerGroupFactory?(c.configure(), c.getJxtaHome());
c.save(); | |
< < | } catch (ConfiguratorException? ce) { | > > | } catch(URISyntaxException? use) { | | | ... | |
< < | } catch (PeerGroupException? pge) { | > > | } catch(ConfigurationException? ce) { | | | ... | |
< < | } | > > | } catch (PeerGroupException? pge) { | | |
| | |
We'll touch on the different types of Profiles shortly but that aside for a moment now is a good time to mention that you can trivially vary the profile used by your AbstractConfigurator implementation via it's constructor, as follows: | |
> > | | | |
... | |
< < | // Profile profile = new Profile(...);
AbstractConfigurator? c = new AbstractConfigurator?(home, Profile.EDGE) {
// AbstractConfigurator? c = new AbstractConfigurator?(home, Profile.SUPER) { | > > | try {
AbstractConfigurator? c = new AbstractConfigurator?(new URI(...), Profile.EDGE) {
// AbstractConfigurator? c = new AbstractConfigurator?(new URI(...), Profile.SUPER) { | | | ...
| | |
... | |
< < | URI profile = getClass().getResourceAsStream("/path/to/my/profile.xml");
AbstractConfigurator? c = new AbstractConfigurator?(home, new Profile(profile)) { | > > | try {
URI p = getClass().getResourceAsStream("/path/to/my/profile.xml");
// URI p = new URI("file:./path/to/my/profile.xml");
AbstractConfigurator? c = new AbstractConfigurator?(new URI(...), new Profile(p)) { | | | ...
| | | throws ConfiguratorException?
| |
< < | As as application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data repository to the running JXTA instance. | > > | As as application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data to the running JXTA instance. | | |
... | |
< < | AbstractConfigurator? c = new AbstractConfigurator?() { | > > | try {
new AbstractConfigurator?() { | | | {
addResource(PROFILE_KEY, "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml"); | | | | |
< < | | > > | | | |
-
-
- process current configuration state
| | | | |
< < | | > > | | | |
-
-
- PlatformConfig
- convenience peer information
- process current configuration state
- PlatformConfig
- profile.xml
| |
< < |
- invocation of any number of setters
| > > |
- invocation of any number of Configurator state modifiers (aka setters)
| | |
- create a PlatformConfig
- invoke getPlatformConfig()
| |
< < |
-
-
- data normalization
- data validation
- data optimization
| > > |
-
-
- normalization
- validation with possible generation of a chained ConfiguratorException?
- optimization
- create PlatformConfig
| | |
- optionally persist configuration artifacts
Internally, Configurator uses Profile.DEFAULT, effectively Profile.EDGE, to establish common use case defaults, after which, any number of setter methods may be invoked to further tune the desired configuration state. | | | throws ConfiguratorException?
| |
< < | The ConfiguratorException object chains all causal exceptions which are in turn accessible via respective iterators: | > > | The ConfiguratorException object chains all causal exceptions which are in turn accessible via getCauses(): | | |
public List getCauses() | | | import java.util.Iterator;
... | |
< < | Configurator c = new Configurator("usr", "pwd"); | > > | private static final String NAME = "name";
private static final String PASSWORD = "password";
Configurator c = new Configurator(NAME, PASSWORD); | | | try {
c.save(); | | | }
| |
< < | Alas, life is typically not so simple and as such we move on to explore a number Configurator methods. Before doing so, let's align with the afore mentioned AbstractConfigurator code sample by overriding the default constructor with an alternative working directory and profile, as follows: | > > | Alas, life is typically not so simple and as such we move on to explore a the available Configurator modifier methods. Before doing so, let's align with the afore mentioned AbstractConfigurator code sample by overriding the default constructor with an alternative working directory and profile, as follows: | | |
...
import java.net.URI;
...
| |
< < | URI home = new URI(...);
Profile profile = new Profile(...);
Configurator c = new Configurator(home, profile); | > > | Configurator c = new Configurator(new URI(...), new Profile(...)); | | | ...
| | | Given Configurator is all encompassing by design and largely a bean (aka property sheet) by implementation the list of setter methods is extensive and but can be broken down into the following categories: | |
< < |
- peer
- name
- description
- id
- debug
- security (user, password)
- network
- seeding rendezVous
- seeding relays
- services
- transports
| > > |
- peer [peer, application and working environment information]
- name [peer name]
- description [peer description, e.g. configuration implementation]
- id [peer id]
- debug [log level]
- security [root certificate principal]
- network [jxta network resources including network, rendezVous and relays]
- seeding rendezVous [initial rendezVous context]
- seeding relays [initial relays context]
- services [peer provisioned services]
- RendezVous [rendezVous service]
- Relay [relay service]
- Proxy [proxy service]
- transports [physical network resources]
- TCP [tcp address(es)]
- HTTP [http address(es)]
| | | | |
< < | | > > |
- endpoint [local resource configuration]
- miscellaneous [e.g. configuration and extensions]
| | | | |
< < | At this time we'll expand on some key members within the configuration family noting that all setters are listed shortly along with a brief description. | > > | At this time we'll expand on some key members within the configuration family noting that all modifiers are listed shortly along with a brief description. | | | Peer information including name, working directory, certificate, and logging information can be specified as follows: | | | Any URI is available to use as a seeding URI and need not resolve at runtime to be used. As an example, for standalone development environments a file based URI is optimal, e.g.: | |
< < | file:///tmp/rdv.txt | > > | file:./myrdv.txt | | |
The following methods can be used to specify RendezVous and Relays network resources in addition to whether or not the to be configured peer can leverage newly discovered services: | | | An Optimizer is a concrete implementation of the Optimizer interface: | |
< < | public class Optimizer { | > > | public interface Optimizer { | | | public void addProperty(String key, String value);
public List getProperty(String key); | | | public void addOptimizers(List)
| |
< < | While Configurator includes several methods, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining setters of specific interest. | > > | An abstract BaseOptimizer can be implemented easing the manufacturing of specialized optimizers, e.g.:
import net.jxta.ext.config.optimzers.BaseOptimizer;
...
Configurator c = new Configurator(new URI(...), new Profile(...));
...
c.addOptimizer(new BaseOptimizer() {
public void optimize(Configurator c) {
...
}
});
...
While Configurator includes several methods, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining modifiers of specific interest. | | | Now that we have a desired configuration state the next step is to generate the representative PlatformConfig object, which is done by inoking the getPlatformConfig() method: | | | Next up, the registered Optimizers are invoked in succession, passing the modified Configurator object in turn. An Optimizer provides the application developer with a concrete API with which to influence configuration life cycle process. | |
< < | Lastly, the resulting configuration state is applied against a series of internal integrity constraints assuring configuration viability. This process, of the 3 listed, can throw a chained ConfiguratorException. | > > | Lastly, the resulting configuration state is applied against a series of internal integrity constraints assuring configuration viability and possibly throwing a ConfiguratorException that is comprised of a chained list of all validation valure root causes. | | | Lastly, one can optionally persist the derived configuration artifacts by invoking the save() method. save() invokes the getPlatformConfig() method in the event is has not been previously invoked.
Profile (aka ext:config/profile) | |
< < | A Profile is a declarative means to manage Configurator instantiation and state via composable presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package.
A series of profile presets exist including:
| EDGE | primarily a service consumer |
| SUPER | primarily a service provisioner |
| LOCAL | primarily useful for development |
| DEFAULT | equivalent to EDGE |
| > > | A Profile is a declarative means to manage Configurator instantiation and state via composable presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. A series of common configuration presets accessible as static members of the Profile class. Further, one can construct an application specific profile in order to manage specialized configuration requirements. | | | | |
< < | Most of the included profiles include subtle variations. Further, one can construct entirely new profiles that support specific application configuration requirements.
All profile addresses are specified as URIs. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Partial URI addresses will be resolved against a contextual template. | > > | All profile addresses are specified as URIs. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Further, partial addresses will be resolved against a backing contextual template. | | | All fields have backing defaults enabling one to specify only the required overrides in order to construct complete configuration profiles. | | |
- net.jxta.ext.config.Profile
| |
< < | Profile includes a number of common presets in the form of a static factory: | > > | Available Profile presets include: | | |
| Profile.EDGE | service consumer |
| |
> > |
| Profile.DEFAULT | synonynm for Profile.EDGE |
| | |
| Profile.EDGE_TCP | service consumer with tcp address |
| Profile.EDGE_HTTP | service consumer with http address |
| Profile.SUPER | rendezVous and relay service provisioner |
| | |
| Profile.LOCAL | loopback only |
| Profile.ADHOC | multicast |
| |
< < | For added flexibility, profiles can also be instantiated with either a URI or InputStream constructor argument the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd schema definition file. URI arguments can specify JAR or external resources easing application deployment by consistently managing application configuration meta data which is readily accessible during runtime. | > > | For added flexibility, profiles can be instantiated with either a URI or InputStream constructor argument the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd schema definition file. URI arguments can specify JAR or external resources easing application deployment by consistently managing application configuration meta data. | | | Following is the prototypical edge profile which can serve as the basis for creating your specialized Profile: | | | Profile p = null;
try { | |
< < | p = new Profile(new URI("file:///tmp/myprofile.xml")); | > > | p = new Profile(new URI("file:./profile.xml")); | | | } catch (MalformedURLException mue) {
...
} catch (URISyntaxException? use) { | | |
...
| |
< < | // p = new Profile(new URI("file:///tmp/myprofile.xml")); | > > | // p = new Profile(new URI("file:./profile.xml")); | | | p = new Profile(getClass().getResourceAsStream("/path/to/my/profile.xml"));
...
| | | The edge profile does not include all possible configuration options as some services are not enabled. Further, defaults are not displayed thereby simplifying overall profile usage. Following is a comprehensive breakdown of the principal configuration elements:
- /jxta [jxta configuration]
| |
< < |
-
- /peer [describes peer, application and environment attributes]
- @name [peer name]
- @descriptor [configuration description]
- @home [working directory
- @trace [log level]
- /description [peer description]
| > > |
-
- /peer [peer, application and working environment information]
- @name [peer name (e.g. "myPeer")]
- @descriptor [peer description, (e.g. "me myself i")]
- @id [peer id (e.g. urn:jxta:uuid-59616261646162614A78746150325033D186291E80AB4CD1875F8FF5C2CE2F9503)]
- @home [working directory (e.g. "file:./myjxta")]
- @trace [log level (e.g. "debug")]
- /description [peer description (e.g. "long version of me myself i")]
| | | | |
< < |
-
-
-
- @enabled [???]
- @principal [credential principal]
- /rootCert [root certificate]
- @address [root certificate address]
- /proxy [http proxy]
- /network [jxta network resources]
- @id [net peer group id]
- @name [net peer group name]
- @description [net peer group description]
| > > |
-
-
-
- @enabled [?security activation? (e.g. "true")]
- @principal [credential principal (e.g. "me")]
- /rootCert [root certificate (e.g. "MIICEDCCAXmgAwIBA...")]
- @address [root certificate address (e.g. "file:./me.cer")]
- /proxy [http proxy (e.g. "http://[usr:pwd@]proxy.org[:port]")]
- @enabled [http proxy activation (e.g. "true")]
- /network [jxta network resources including network, rendezVous and relays]
- @id [net peer group id (e.g. "urn:jxta:uuid-5702345907204359072934759073490702")]
- @name [net peer group name (e.g. "MyNet")]
- @description [net peer group description (e.g. "me myself i network")]
| | |
-
-
- /rendezVous [seeding rendezVous]
| |
< < |
-
-
-
- @bootstrap [seeding address]
- @discovery [leverage discovered rendezVous peers]
- /address [seed address]
| > > |
-
-
-
- @bootstrap [seeding address (e.g. "file:./rdv.txt")]
- @discovery [leverage discovered rendezVous peers activation (e.g. "false")]
- /address [rendezVous seed address (e.g. "tcp://1.2.3.4:9701")]
| | | | |
< < |
-
-
-
- @bootstrap [seeding address]
- @discovery [leverage discovered relay peers (nop)]
- /address [seed address]
| > > |
-
-
-
- @bootstrap [seeding address (e.g. "file:./rly.txt")]
- @discovery [leverage discovered relay peers activation (e.g. "false") - nop]
- /address [relay seed address, (e.g. "tcp://1.2.3.4:9701")]
| | |
-
- /transport [physical network resources]
| |
< < | | > > |
-
-
- /tcp [tcp address(es)]
- @enabled [tcp transport activation (e.g. "true")]
| | | | |
< < | | > > |
-
-
-
-
- @enabled [server activation (e.g. "true")]
| | | | |
< < |
-
-
-
-
- /address [ipv6 or ipv4 address]
- @range [port range]
- /multicast [multicast]
- @enable [enabled]
- @size [size]
- /publicAddress [public address]
- /proxy [proxy]
- /http [http]
| > > |
-
-
-
-
- @enabled [client activation (e.g. "true")]
- /address [ipv6 or ipv4 tcp address (e.g. "tcp://1.2.3.4:9701")]
- @range [upper bound port range (e.g. 100)]
- /multicast [multicast (e.g. "udp://224.0.1.85:1234")]
- @enable [multicast activation (e.g. "false")]
- @size [multicat packet size (e.g. "16338")]
- /publicAddress [public address (e.g. "tcp://5.6.7.8:9701"]
- @exclusive [don't publish tcp address (e.g. "false")]
- /proxy [tcp proxy (e.g. "tcp://5.6.7.8:8080")]
- @enabled [proxy activation (e.g. "false")]
- /http [http address(es)]
- @enabled [http transport activation (e.g. "true")]
| | | | |
< < | | > > |
-
-
-
-
- @enabled [server activation (e.g. "false")]
| | | | |
< < |
-
-
-
-
- /address [[ipv6 or ipv4 address]
- /publicAddress [public address]
- /proxy [proxy]
| > > |
-
-
-
-
- @enabled [client activation (e.g. "true")]
- /address [[ipv6 or ipv4 tcp address ("http://1.2.3.4:9700")]
- @range [upper bound port range (e.g. "100")]
- /publicAddress [public address (e.g. "http://5.6.8.9:9700")]
- @exclusive [don't publish http address (e.g. "false")]
- /proxy [http proxy (e.g. "http://5.6.7.8:8080")]
- @enabled [proxy activation (e.g. "false")]
| | |
-
- /service [provisioned services]
| |
< < |
-
-
- /rendezVous [rendezVous]
- @enabled [enabled]
- /autoStart [auto rendezVous]
- /relay [relay]
- @enabled [enabled]
- @queueSize [queue size]
| > > |
-
-
- /rendezVous [rendezVous service]
- @enabled [rendezVous activation (e.g. "false")]
- /autoStart [auto rendezVous (e.g. "120000")]
- @enabled [auto rendezVous activation (e.g. "false")]
- /relay [relay service]
- @enabled [relay activation (e.g. "false")]
- @queueSize [relay queue size (e.g. "20")]
| | | | |
< < |
-
-
-
-
- @enabled [enabled]
- @maximum [maximum leases]
- @lease [lease time]
| > > |
-
-
-
-
- @enabled [server activation (e.g. "false")]
- @maximum [maximum leases (e.g. "100")]
- @lease [lease time (e.g. "7200000")]
| | | | |
< < |
-
-
-
-
- @enabled [enabled]
- @maximum [maximum leases]
- @lease [lease time]
- /endpoint [endpoint]
- /proxy [proxy]
| > > |
-
-
-
-
- @enabled [client activation (e.g. "true")]
- @maximum [maximum leases (e.g. "100")]
- @lease [lease time (e.g. "7200000")]
- /endpoint [local resource configuration]
- @queueSize [queue size (e.g. "100")]
- /proxy [proxy service]
- @enabled [proxy activation (e.g. "false")]
| | |
-
- /configuration [configuration]
| |
< < |
(ed: i'm not a huge fan of the above format) | > > |
-
-
-
- @class [optimizer class name (e.g. "path.to.MyOptimizer")]
- /property [property value (e.g. "path.to.MyOptimizer.foo")]
- @name [property key (e.g. "bar")]
| | | To close on this section, one can trivially instantiate a Configurator, or AbstractConfigurator, with a named Profile as follows: | | | import java.net.URI;
... | |
< < | URI profile = new URI(...);
Configurator c = new Configurator(new Profile(profile)); | > > | Configurator c = new Configurator(new Profile(new URI(...))); | | |
As we've seen above, AbstractConfigurators can be instantiated with a Profile in like fashion, further simplifying JXTA configuration within one's application, all the while the underlying Configurator can readily be manipulated via any of the available APIs. This model supports configuration experimentation without having to recompile. Lastly, profiles are used internally by the Configurator class and as such are most assuredly first class citizens within the ext:config package. | | | Lastly, the ext:config/ui tier provides an extensible UI above the ext:config/profile tier by providing Swing utilities to aid in interactive configuration. See JXTA ext:UI doc for more information. | |
> > | The principal ext:config/ui class is:
- net.jxta.ext.config.ui.Configurator
| | | (ed: wip)
|
|
<<O>> Difference Topic
ExtConfig
(15 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease | | | Dependencies | |
< < | The required ext:config jars are the following: | > > | The required ext:config jars: | | | | | |
-
- jdom.jar (required only for UI)
- swixml.jar (required only for UI)
| |
< < | These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section. | > > | These jars can be obtained from the JXTA Download Site. | | | Introduction | | |
Profile (aka ext:config/profile) | |
< < | A Profile is a declarative means to manage Configurator instantiation and state via collapsible presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. | > > | A Profile is a declarative means to manage Configurator instantiation and state via composable presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. | | | A series of profile presets exist including: | |
< < |
| | |
| EDGE | primarily a service consumer |
| SUPER | primarily a service provisioner |
| LOCAL | primarily useful for development |
| | | Profile includes a number of common presets in the form of a static factory: | |
< < |
| | |
| Profile.EDGE | service consumer |
| Profile.EDGE_TCP | service consumer with tcp address |
| Profile.EDGE_HTTP | service consumer with http address |
|
|
<<O>> Difference Topic
ExtConfig
(14 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease | | | The ext:config/api library is principally a bean (or property sheet) styled API with which one can construct, manipulate and generate a valid JXTA configuration in the form of a PlatformConfig object. The principal classes in ext:config/api are AbstractConfigurator and Configurator. | |
< < | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles" which are largely configuration presets. The principal class in in ext:config/profile is *net.jxta.ext.config. | > > | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles" which are largely configuration presets. The principal class in in ext:config/profile is:
- net.jxta.ext.config.Profile
| | | The ext:config/ui provides a series of user interface elements to manage JXTA configuration data. | | |
- root certificate
- HTTP Proxy
| |
< < | The JXTA Network information specifies JXTA Network Services upon which the to be instantiated peer will leverage as initialing seeding (aka bootstrap) information: | > > | The JXTA Network information specifies JXTA Network Services upon which the to be instantiated peer will leverage as initialing seeding (aka bootstrap) information: | | | | | | public void setInfrastructurePeerGroupDescription(String description)
| |
< < | In order to establish initial JXTA network context it is optimal to specify seeding (aka bootstrap) information after which the peer is free to leverage discovered resources as needed at runtime. Seeding RendezVous and Relays are typical and in fact for "edge" scenarios only the later is required. RendezVous peers serve as a connection resource with which newly instantiated peers can leverage in the form of leases. Relay relationships are established for peers that can not otherwise communicate with one another in a direct fashion which is common for applications running behind corporate firewalls accessing services available on the open internet. These relationships change dynamically as the netork itself changes yet the developer is presented with a unified view of the overall network. A seeding address, be it RendezVous or Relay, takes the form of a fully qualified IP based URI, with examples being: | > > | In order to establish initial JXTA network context it is optimal to specify seeding (aka bootstrap) information after which the peer is free to leverage discovered resources as needed at runtime. Seeding RendezVous and Relays are typical and in fact for "edge" scenarios only the later is required. RendezVous peers serve as a connection resource with which newly instantiated peers can leverage in the form of leases. Relay relationships are established for peers that can not otherwise communicate with one another in a direct fashion which is common for applications running behind corporate firewalls accessing services available on the open internet. These relationships change dynamically as the netork itself changes yet the developer is presented with a unified view of the overall network. A seeding address, be it RendezVous or Relay, takes the form of a fully qualified IP based URI, with examples being: | | |
tcp://1.2.3.4:9701
http://1.2.3.4:9700
| |
< < | A seeding URI is a simply a resource that returns a list of available seeding addresses as defined above. As such, as seeding URI is often specified with a common domain name, eg: | > > | A seeding URI is a simply a resource that returns a list of available seeding addresses as defined above. As such, as seeding URI is often specified with a common domain name, e.g.: | | |
http://rdv.jxtahosts.net/cgi-bin/rendezvous.cgi?2
http://rdv.jxta.hosts.net/cgi-gin/relays.cgi?2
| |
< < | Any URI is available to use as a seeding URI and need not resolve at runtime to be used. As an example, for standalone development environments a file based URI is optimal, eg: | > > | Any URI is available to use as a seeding URI and need not resolve at runtime to be used. As an example, for standalone development environments a file based URI is optimal, e.g.: | | |
file:///tmp/rdv.txt |
|
<<O>> Difference Topic
ExtConfig
(13 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
| |
< < | ext:config : extensible JXTA configuration with ease. | > > | ext:config : extensible JXTA configuration with ease | | | Table of Contents | | | Principal JXTA configuration information is collected the form of a PlatformConfig object. For file based persistent environments, a PlatformConfig XML file often resides within the application's specified working directory, aka JXTA HOME, as a JXTA Platform start up precondition. In memory only application environments as well as runtime configuration support is also available and is actively under development. | |
< < | The ext:config/api library is principally a bean or property sheet styled API with which one can construct, manipulate and generate a valid JXTA configuration in the form of a PlatformConfig object. The principal classes in ext:config/api are AbstractConfigurator and Configurator. | > > | The ext:config/api library is principally a bean (or property sheet) styled API with which one can construct, manipulate and generate a valid JXTA configuration in the form of a PlatformConfig object. The principal classes in ext:config/api are AbstractConfigurator and Configurator. | | | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles" which are largely configuration presets. The principal class in in ext:config/profile is *net.jxta.ext.config. | | | Following are the steps necessary to compile and run the included functional code samples. The prerequisites are: | |
< < |
- J2SE (1.5 recommended)
- Ant
| > > | | | | Obtain a working copy of the ext-config-lab.zip code samples and uncompress it accordingly followed by changing your working directory to that of the top-level jxta directory provided by the distribution. Running Ant with no arguments will display the usage message: | | |
Resources | |
< < |
- ext:config API - note: package net.jxta.ext.config
- ext-config.zip
- JXTA Downloads
- JXTA Bootstrap
- JXTA jar dependencies
- Daniel Brookshier's Autoconfig example?
| > > | | | | -- JamesTodd - 01 Feb 2005
-- updated.RayGao - 21, Nov. 2005 |
|
<<O>> Difference Topic
ExtConfig
(12 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease. | | | The required ext:config jars are the following:
| |
> > |
-
- bcprov-jdk14.jar
- log4j.jar
- javax.servlet.jar
| | | | |
> > | | | |
- 3rd party
- jdom.jar (required only for UI)
- swixml.jar (required only for UI)
| | |
- reference the specified profile
| |
< < | When specifying a non-default working directory, aka JXTA Home, it is required to specify the system property named JXTA_HOME the value of the absolute file path. Further, it is incumbent upon the developer to copy into the working directory "private network" resources. These issues will be resolved in the next release (see issue #1488 and #1500). | > > | When specifying a non-default working directory, aka JXTA Home, it is currently required to specify the system property named JXTA_HOME the value of the absolute file path. Further, it is incumbent upon the developer to copy into the working directory "private network" resources. These issues will be resolved in the next release (see issue #1488 and #1500). | | |
Barring exceptions, one can then instantiate a JXTA Platform by referencing the derived JXTA Home and it's included artifacts, namely PlatformConfig.
| |
< < | A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently configure and start a peer instance in addition to optionally persisting the configuration artifacts: | > > | A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently configure and start a peer instance in addition to optionally persisting the configuration artifacts (see commons/modules/ext): | | |
... | | | | |
< < |
</font. | > > | | | |
At this time we'll expand on some key members within the configuration family noting that all setters are listed shortly along with a brief description. | |
< < | Peer information including name, working directory and logging information can be specified as follows: | > > | Peer information including name, working directory, certificate, and logging information can be specified as follows: | | | | |
< < | public void setPeerName(String) | > > | public void setName(String)
public void setPeerId(PeerID)
public void setDescription(String) | | | public void setJxtaHome(URI) | |
> > | public void setRootCertificate(Certificate)
public void setRootCertificateAddress(URI)
public void setRootCertificateBase64(String)
public void setSecurity(String, String) | | | public void setTrace(Trace) | |
> > | public void setRendezVousAutoStart(long) | | | | |
< < | The default JXTA network is known as the Public Network (aka PubNet?) which serves as an available testbed network. Specifying a non-default JXTA network is achieved by invoking the "infrastructure group" APIs, which allows one to construct, deploy, operate and scope systems resources to a dedicated network of services: | > > | The default JXTA network is known as the Public Network (aka PubNet) which serves as an available testbed network. Specifying a non-default JXTA network is achieved by invoking the "infrastructure group" APIs, which allows one to construct, deploy, operate and scope systems resources to a dedicated network of services: | | |
public void setInfrastructurePeerGroupId(PeerGroupID id) | | | The following methods can be used to specify RendezVous and Relays network resources in addition to whether or not the to be configured peer can leverage newly discovered services: | |
< < | public void setRendezVousBootstrapAddress(URI) | | | public void setRendezVous(URI)
public void addRendezVous(URI)
public void setRendezVous(List) | |
< < | public void setRendezVousDiscovery(boolean) | > > | public void setRendezVousBootstrapAddress(URI) | | | | |
< < | public void setRelayBootstrapAddress(URI) | > > | public void setRendezVousDiscovery(boolean) | | | public void setRelays(URI) | | | public void setRelays(List) | |
> > | public void setRelayBootstrapAddress(URI) | | | public void setRelaysDiscovery(boolean)
| | | Optimizers provide the opportunity to apply application specific configuration heuristics against a Configurator object. Optimizers may be provided with a series of name-values tuples and are supported via Profile constructs. Further, the Configurator implementation may opt to apply a number of internal optimizers during PlatformConfig generation. | |
< < | Following is a terse overview of the configuration attribute setters followed by a brief narrative presented in tabular form: | > > | Optimizers are applied to the Configurator via the following methods: | | | | |
< < |
| method | description |
| setDescriptor(String) | configuration descriptor |
| setName(String) | peer name |
| setDescription(String) | peer description |
| setTrace(Trace) | log level |
| setPeerId(PeerID) | peer id |
| setRendezVous(boolean) | rendezVous service enabled |
| setRendezVous(URI) | seeding rendezVous address |
| addRendezVous(URI) | add seeding rendezVous address |
| setRendezVous(List) | seeding rendezVous addresses |
| addRendezVous(List) | add seeding rendezVous addresses |
| setRendezVousAutosStart(long) | auto rendezVous attribute |
| setRelay(boolean) | relay service enabled |
| setRelay(URI) | seeding relay address |
| addRelay(URI) | add seeding relay address |
| setRelay(List) | seeding relaly addresses |
| addRelays(List) | add seeding relaly addresses |
| setRelayIncoming(boolean) | relay client |
| setRelayIncomingMaximum(int) | maximum server lease support |
| setRelayIncomingLease(long) | server lease duration |
| setRelayOutgoing(boolean) | relay server |
| setRelayOutgoingMaximum(int) | maximum client lease support |
| setRelayOutgoingLease(long) | client lease duration |
| setRelayQueueSize(int) | relay queue |
| setTransport(Transport) | physical address |
| addTransport(Transport) | add physical address |
| addTransports(List) | add physical addresses |
| setTransports(List) | physical addresses |
| setSecurity(boolean) | security is enabled |
| setSecurity(String, String) | security principal and password |
| setRootCertificateAddress(URI) | root certificate address |
| setRootCertificate(Certificate) | root certificate |
| setRootCertificateBase64(String) | root certificate as Base64 |
| setPeerProxyAddress(URI) | proxy peer |
| setEndpointOutgoingQueueSize(int) | endpoint queue capacity |
| setProxy(boolean) | proxy service enabled |
| setInfrastructurePeerGroupId(PeerGroupID?) | infrastructure network id |
| setInfrastructurePeerGroupName(String) | infrastructure group name |
| setInfrastructurePeerGroupDescription(String) | infrastructure group description |
| setRendezVousBootstrapAddress(URI) | seeding address |
| setRendezVousDiscovery(boolean) | directs leasing from discovered rendezVous peers |
| setRelaysBootstrapAddress(URI) | seeding address |
| setRelaysDiscovery(boolean) | directs leasing from discovered relay peers |
| setPlatformConfig(PlatformConfig) | basis for configuration state |
| setConfigParams(ConfigParams?) | basis for configuration state |
| setReconfigure(booleans) | reconfiguration upon start indicator |
| addOptimizer(Optimizer) | add optimizer |
| addOptimizers(List) | add optimizers |
| > > |
public void addOptimizer(Optimizer) | | | | |
< < | While all of the above methods are readily invokable, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining setters of specific interest. | > > | public void addOptimizers(List)
While Configurator includes several methods, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining setters of specific interest. | | | Now that we have a desired configuration state the next step is to generate the representative PlatformConfig object, which is done by inoking the getPlatformConfig() method: | | |
Profile (aka ext:config/profile) | |
< < | Provides a means to declaratively manage Configurator processes by quantifing varying configuration classes into common domains in the form of "profiles." | > > | A Profile is a declarative means to manage Configurator instantiation and state via collapsible presets that represent distinct configuration models. ext:config/profile represents this tier of the configuration package. | | | A series of profile presets exist including: | | |
| LOCAL | primarily useful for development |
| DEFAULT | equivalent to EDGE |
| |
< < | Most of the included profiles include subtle variations. Further, one can construct entirely new profiles that support specific application requirements. | > > | Most of the included profiles include subtle variations. Further, one can construct entirely new profiles that support specific application configuration requirements. | | | | |
< < | All addresses are of the form URI. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Partial URI addresses will be templated with the respective context such as the local IP address, etc. | > > | All profile addresses are specified as URIs. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Partial URI addresses will be resolved against a contextual template. | | | All fields have backing defaults enabling one to specify only the required overrides in order to construct complete configuration profiles. | |
< < | The principal ext:config/profile class is: | > > | The principal ext:config/profile class is: | | |
- net.jxta.ext.config.Profile
| |
< < | For added flexibility, profiles can also be instantiated with either an URL or InputStream parameter the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd file. This approach eases deployments by centrally managing application configuration meta data which is then accessed at application runtime. | > > | Profile includes a number of common presets in the form of a static factory:
| profile | description |
| Profile.EDGE | service consumer |
| Profile.EDGE_TCP | service consumer with tcp address |
| Profile.EDGE_HTTP | service consumer with http address |
| Profile.SUPER | rendezVous and relay service provisioner |
| Profile.SUPER_TCP | rendezVous and relay service provisioner with tcp address |
| Profile.SUPER_HTTP | rendezVous and relay service provisioner with http address |
| Profile.RENDEZVOUS | rendezVous service provisioner |
| Profile.RENDEZVOUS_TCP | rendezVous service provisioner with tcp address |
| Profile.RENDEZVOUS_HTTP | rendezVous service provisioner with http address |
| Profile.RELAY | relay service provisioner |
| Profile.RELAY_TCP | relay service provisioner with tcp address |
| Profile.RELAY_HTTP | relay service provisioner with http address |
| Profile.LOCAL | loopback only |
| Profile.ADHOC | multicast |
For added flexibility, profiles can also be instantiated with either a URI or InputStream constructor argument the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd schema definition file. URI arguments can specify JAR or external resources easing application deployment by consistently managing application configuration meta data which is readily accessible during runtime. | | | | |
< < | Following is the prototypical edge profile which can serve as the basis for creating your specialized Profile: | > > | Following is the prototypical edge profile which can serve as the basis for creating your specialized Profile: | | |
<!DOCTYPE org.jxta:configuration> | | |
| |
< < | Assuming the above profile was copied to a file, say /tmp/myprofile.xml, and modified as needed one could instantiate the resulting specialized Profile as follows: | > > | Default profile information is typically not displayed, further easing extension by allowing one to specify only the overrides. A future Profile.EDGE release will largely be an emtpy file as all the values are defaults, allowing one to add only data elements which are specified as overrides.
Although we've seen Profile instantiation in the above code examples it might prove enlightening to walk through a couple of use cases. The following example instantiates a Profile from a file based URI resource: | | |
import net.jxta.ext.config.Profile;
import net.jxta.ext.config.ResourceNotFoundException; | |
< < | import java.net.URL;
import java.net.MalformedURLException; | > > | import java.net.URI;
import java.net.URISyntaxException; | | | ...
Profile p = null;
try { | |
< < | p = new Profile(new URL("file:///tmp/myprofile.xml")); | > > | p = new Profile(new URI("file:///tmp/myprofile.xml")); | | | } catch (MalformedURLException mue) { | |
< < | mue.printStackTrace();
} catch (ResourceNotFoundException? rnfe) {
rnfe.printStackTrace();
}
The edge profile does not include all possible configuration options as some services are not enabled. Further, defaults, when used, are not duplicated thereby simplifying overall profile usage. Following is a comprehensive breakdown of the principal configuration elements:
| peer | peer description | | | | |
| | descriptor | profile description | | | |
| | home | JXTA_HOME | | | |
| | trace | debug level | | | |
| | security | | | | |
| | proxy | | | | |
| network | subscribed services | | | | |
| | id | network peer group id | | | |
| | name | network name | | | |
| | description | network description | | | |
| | rendezVous | subscribed rendezVous services | | | |
| | | bootstrap | seeding URL | | |
| | | discovery | disallow usage of discovered rendezVous | | |
| | | address(es) | service URI | | |
| | relays | subscribed relays services | | | |
| | | bootstrap | seeding URL | | |
| | | discovery | disallow usage of discovered relays | | |
| | | address(es) | service URI | | |
| transport | peer address(es) | | | | |
| | tcp | TCP endpoint | | | |
| | | address | endpoint URI | | |
| | | range | port range | | |
| | | multicast | muticast URI | | |
| | | | enabled | multicast controller | |
| | | publicAddress | public endpoint URI | | |
| | | | enabled | public address controller | |
| | | proxy | proxy address | | |
| | http | HTTP endpoint | | | |
| | | address | endpoint URI | | |
| | | range | port range | | |
| | | publicAddress | public endpoint URI | | |
| | | proxy | proxy address | | |
| service | provisioned services | | | | |
| | rendezVous | provisioned rendezVous service | | | |
| | | enabled | rendezVous controller | | |
| | | autoStart | rendezVous provisioning policy in milliseconds | | |
| | | | enabled | autoStart controller | |
| | relay | provisioned relay service | | | |
| | | enabled | relay controller | | |
| | | queueSize | relay queue size | | |
| | | incoming | | | |
| | | | enabled | incoming controller | |
| | | | maximum | maximum messages | |
| | | | lease | lifetime in milliseconds | |
| | | outgoing | | | |
| | | | enabled | outgoing controller | |
| | | | maximum | maximum messages | |
| | | | lease | lifetime in milliseconds | |
| | endpoint | | | | |
| | | queueSize | message queue size | | |
| | proxy | | | | |
| | | enabled | proxy controller | | |
| configuration | | | | | |
| | optimizer(s) | configuration optimization | | | |
| | | class | optimizer class name | | |
| | | | property(s) | optimizer attributes | |
| | | | | name | value |
| > > | ...
} catch (URISyntaxException? use) {
...
}
| | | | |
< < | Bringing it all together, one can trivially instantiate a Configurator with a selected Profile instance as a constructor argument as follows: | > > | While the following example instantiates a Profile from a class resource: | | | | |
> > | ...
// p = new Profile(new URI("file:///tmp/myprofile.xml"));
p = new Profile(getClass().getResourceAsStream("/path/to/my/profile.xml"));
...
The edge profile does not include all possible configuration options as some services are not enabled. Further, defaults are not displayed thereby simplifying overall profile usage. Following is a comprehensive breakdown of the principal configuration elements:
- /jxta [jxta configuration]
- /peer [describes peer, application and environment attributes]
- @name [peer name]
- @descriptor [configuration description]
- @home [working directory
- @trace [log level]
- /description [peer description]
- /security [credentials]
- @enabled [???]
- @principal [credential principal]
- /rootCert [root certificate]
- @address [root certificate address]
- /proxy [http proxy]
- /network [jxta network resources]
- @id [net peer group id]
- @name [net peer group name]
- @description [net peer group description]
- /rendezVous [seeding rendezVous]
- @bootstrap [seeding address]
- @discovery [leverage discovered rendezVous peers]
- /address [seed address]
- /relays [seeding relays]
- @bootstrap [seeding address]
- @discovery [leverage discovered relay peers (nop)]
- /address [seed address]
- /transport [physical network resources]
- /tcp [tcp]
- @enabled [enabled]
- /incoming [server]
- /outgoing [client]
- /address [ipv6 or ipv4 address]
- @range [port range]
- /multicast [multicast]
- @enable [enabled]
- @size [size]
- /publicAddress [public address]
- /proxy [proxy]
- /http [http]
- @enabled [enabled]
- /incoming [server]
- /outgoing [client]
- /address [[ipv6 or ipv4 address]
- /publicAddress [public address]
- /proxy [proxy]
- /service [provisioned services]
- /rendezVous [rendezVous]
- @enabled [enabled]
- /autoStart [auto rendezVous]
- /relay [relay]
- @enabled [enabled]
- @queueSize [queue size]
- /incoming [server]
- @enabled [enabled]
- @maximum [maximum leases]
- @lease [lease time]
- /outgoing [client]
- @enabled [enabled]
- @maximum [maximum leases]
- @lease [lease time]
- /endpoint [endpoint]
- /proxy [proxy]
- /configuration [configuration]
(ed: i'm not a huge fan of the above format)
To close on this section, one can trivially instantiate a Configurator, or AbstractConfigurator, with a named Profile as follows:
import net.jxta.ext.config.Configurator;
import net.jxta.ext.config.Profile;
...
| | | Configurator c = new Configurator(Profile.EDGE);
| |
< < | The resulting Configurator can readily be manipulated by any of the available APIs. As such, profiles are used to declaratively instantiate an application Configurator via a configuration meta-model. The resulting Configurator instance can, in turn, be adjusted via any of the provided APIs. Using Profiles one can readily experiment with varying models without having to recompile a line of code. Lastly, profiles are used internally by the Configurator class during instantiation to set the relevant defaults. | > > | A specialized Profile can be readily used as follows:
...
import java.net.URI;
...
URI profile = new URI(...);
Configurator c = new Configurator(new Profile(profile));
As we've seen above, AbstractConfigurators can be instantiated with a Profile in like fashion, further simplifying JXTA configuration within one's application, all the while the underlying Configurator can readily be manipulated via any of the available APIs. This model supports configuration experimentation without having to recompile. Lastly, profiles are used internally by the Configurator class and as such are most assuredly first class citizens within the ext:config package. | | |
UI (aka ext:config/ui) | |
< < | Lastly, the ext:config/ui tier provides an extensible UI above the afore mentioned ext:config/profile tier.
It is done in the manner of Swing (Event model) with xxxModels and xxxListeners. see JXTA ext:UI doc for detail. | > > | Lastly, the ext:config/ui tier provides an extensible UI above the ext:config/profile tier by providing Swing utilities to aid in interactive configuration. See JXTA ext:UI doc for more information. | | | | |
< < | wip ... | > > | (ed: wip) | | |
Just Code | | | The excercises are contained under the src directory and organized as incremental and progressive code samples. The lib directory includes the necessary JXTA and ext:config libraries: | |
< < | JXTA jars: | > > | JXTA JARs: | | | | |
< < |
- bcprov-jdk14.jar
- javax.servlet.jar
- jxta.jar
- log4j.jar
- org.mortbay.jetty.jar
ext:config jars:
- jaxen-core.jar
- jaxen-jdom.jar
- jdom.jar
- jxtaext.jar
- saxpath.jar
note: the ext:config jars will likely soon be replaced with the JAXP 1.3 equivalents | > > |
- bcprov-jdk14.jar
- javax.servlet.jar
- jxta.jar
- jxtaext.jar
- log4j.jar
- org.mortbay.jetty.jar
| | | To run an excercise simply provide the excercise directory as an Ant argument: | | | Have fun! Learn by doing! | |
< < | Caution editing your profile.xml | > > | | | |
Resources |
|
<<O>> Difference Topic
ExtConfig
(11 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease. | | | ...
URI home = new URI(...); | |
< < | | > > | // xxx: specifying a System property for JXTA_HOME is not required in future releases | | | System.setProperty("JXTA_HOME", new File(home).getAbsolutePath()); | |
< < | | | | Profile profile = new Profile(...);
AbstractConfigurator? c = new AbstractConfigurator?(home, profile) {
| | | c.setTransport(tt);
| |
< < | It should be noted that doing the equivalent using only Profile constructs is significantly more intuitive and less prone to error. We will touch on this topic shortly. Till then, with a Transport object in hand, we can augment the configuration state via the following methods: | > > | It should be noted that doing the equivalent Transport configuration using Profile constructs is significantly more intuitive and less prone to error, a topic we will touch on shortly. Till then, with a Transport object in hand, we can augment the configuration state via the following methods: | | |
public void setTransport(Transport) | | | public void setTransports(List)
| |
> > | An Optimizer is a concrete implementation of the Optimizer interface:
public class Optimizer {
public void addProperty(String key, String value);
public List getProperty(String key);
public void optimize(Configurator c);
}
Optimizers provide the opportunity to apply application specific configuration heuristics against a Configurator object. Optimizers may be provided with a series of name-values tuples and are supported via Profile constructs. Further, the Configurator implementation may opt to apply a number of internal optimizers during PlatformConfig generation. | | | Following is a terse overview of the configuration attribute setters followed by a brief narrative presented in tabular form:
| | | While all of the above methods are readily invokable, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining setters of specific interest. | |
> > | Now that we have a desired configuration state the next step is to generate the representative PlatformConfig object, which is done by inoking the getPlatformConfig() method: | | | | |
> > |
public PlatformConfig getPlatformConfig()
throws ConfiguratorException
| | | | |
> > | The following steps are preformed during PlatformConfig generation: | | | | |
> > |
- normalization
- optimzation
- validation
- PlatformConfig generation
| | | | |
> > | All exceptions that may occur as a result of the above processing is captured in a single ConfiguratorException in for form a chained exception list, as noted above. | | | | |
< < | The save methods actually invoke the getPlatformConfig() method. As such, the only real function of the save() methods are to persist a PlatformConfig, as XML, to the relevant file system. With that, our attention turns back to the getPlatformConfig() method. In short, the following steps are executed in order resulting in either a valid PlatformConfig object or a causal ConfiguratorException exception:
- normalization
- optimization
- validation
- PlatformConfig construction
| > > | Normalization is the process that fills in any blank attributes with the specified default values. Profile macros are expanded at this time. This step of the process generates no exceptions. | | | | |
< < | Taking each of these in turn we start with normalization. Normalization starts out by filling in any blank entries with the relvant defaults. No exceptions or faults are generated during this process. wip: describe address macro expansion | > > | Next up, the registered Optimizers are invoked in succession, passing the modified Configurator object in turn. An Optimizer provides the application developer with a concrete API with which to influence configuration life cycle process. | | | | |
< < | Next up, the optimizer kicks in by iterating the current and recently normalized Configurator state through all registered Optimizers in succession. wip: detail Optimizer interface, registration | > > | Lastly, the resulting configuration state is applied against a series of internal integrity constraints assuring configuration viability. This process, of the 3 listed, can throw a chained ConfiguratorException. | | | | |
< < | Following the resultant Configurator state is exercised against a series of internal heuristics that check for PlatformConfig viability. This process, alone, can throw a ConfiguratorException. | > > | Lastly, one can optionally persist the derived configuration artifacts by invoking the save() method. save() invokes the getPlatformConfig() method in the event is has not been previously invoked. | | |
Profile (aka ext:config/profile) |
|
<<O>> Difference Topic
ExtConfig
(10 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config : extensible JXTA configuration with ease. | | |
public PlatformConfig updatePlatformConfig(PlatformConfigurator configurator) | |
< < | throws ConfiguratorException? {
...
} | > > | throws ConfiguratorException? | | |
Lastly, the configure() method can be invoked to trigger the configuration life cycle:
public PlatformConfig configure() | |
< < | throws ConfiguratorException? {
...
} | > > | throws ConfiguratorException? | | |
The derived PlatformConfig can be used to immediately instantiate a peer or passed along to another process as is. With that in mind, a comprehensive code example is as follows: | | |
- Profile
- alternative backing Configurator delegate
| |
< < | Typical usage is to override the defaults by specifying an application specific working home (aka JXTA HOME) and application specific Profile: | > > | Typical usage is to override the defaults by specifying an application specific working home (aka JXTA HOME) and application specific Profile. Following is such an example with the addition of a work we will address shortly: | | |
... | | | ...
import net.jxta.ext.config.Profile
import java.net.URI; | |
< < | | | | ... | |
> > | | | | URI home = new URI(...); | |
> > |
System.setProperty("JXTA_HOME", new File(home).getAbsolutePath());
| | | Profile profile = new Profile(...);
AbstractConfigurator? c = new AbstractConfigurator?(home, profile) {
| | |
- create and/or read the specified working directory
- reference the specified profile
| |
< < | Barring exceptions, one can then instantiate a JXTA Platform by referencing the derived JXTA Home and it's included artificats, namely PlatformConfig. | > > |
When specifying a non-default working directory, aka JXTA Home, it is required to specify the system property named JXTA_HOME the value of the absolute file path. Further, it is incumbent upon the developer to copy into the working directory "private network" resources. These issues will be resolved in the next release (see issue #1488 and #1500).
Barring exceptions, one can then instantiate a JXTA Platform by referencing the derived JXTA Home and it's included artifacts, namely PlatformConfig. | | |
A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently configure and start a peer instance in addition to optionally persisting the configuration artifacts: | | |
public PlatformConfig getPlatformConfig() | |
< < | throws ConfiguratorException? { | > > | throws ConfiguratorException? | | |
As as application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data repository to the running JXTA instance. | | |
-
-
- working directory
- profile
- configuration delegate
| |
< < |
- implement createPlatformConfig() for new PlatformConfig generation
- optionally implement updatePlatformConfig() for PlatformConfig updates
| > > |
-
- process current configuration state
- PlatformConfig
- profile.xml
| | |
- create a PlatformConfig
- invoke configure to create and persist a PlatformConfig
- invokes createPlatformConfig()
| | | When implementing AbstractConfigurator createPlatformConfig() and updatePlatformConfig() methods you will work directly with the underlying configuration delegate, aptly named Configurator. With that, we turn our attention to the Configurator API. | |
< < | The Configurator class serves to programmatically create new or update existing PlatformConfig instances by managing all configuration attributes in addition to performing data integrity and optional data optimizations. As mentioned above, a Configurator is most often managed via an AbstractConfigurator implementation although it can just as easily be used as a standalone component.
The lifecycle of a Configurator is typically quite short. Initially, a few key static constructs are invoked in order to establish a baseline Configurator instance. Firstly, a default PlatformConfig object is processed followed by the protected Profile.SEED profile. Lastly, the default JXTA_HOME is set to the .jxta directory hosted in the user's home directory, programmactically as follows: | > > | The Configurator class serves to programmatically create new or update existing PlatformConfig instances by managing all configuration attributes in addition to performing data integrity and optional data optimizations. As mentioned above, a Configurator is most often managed via an AbstractConfigurator implementation although it can just as easily be used as a standalone component. | | | | |
< < |
setHome(new File(new File(System.getProperty("user.home")), ".jxta"));
| > > | The lifecycle of a Configurator is typically quite short and follows along the lines of: | | | | |
< < | note: Setting the JXTA_HOME via a static method has proven problematic and as such is currently under review. A likely refactor may include the JXTA_HOME as a constructor argument. | > > |
- instantiation
- optionally specifying
- working directory
- profile
- PlatformConfig
- convenience peer information
- process current configuration state
- PlatformConfig
- profile.xml
- invocation of any number of setters
- create a PlatformConfig
- invoke getPlatformConfig()
- data normalization
- data validation
- data optimization
- optionally persist configuration artifacts
| | | | |
< < | Upon instantiation, the Configurator object looks for a PlatformConfig in the specified JXTA_HOME and if found is processed to establish the relevant instance state. If a PlatformConfig is not found then a Profile by the name profile.xml hosted in the JXTA_HOME directory will be sought out and if found used to specify the relevant instance state. Failing to find
either of the PlatformConfig and profile.xml files in the specified JXTA_HOME the default profile Profile.DEFAULT (which is effectively Profile.EDGE) will be used to establish the instance state. | > > | Internally, Configurator uses Profile.DEFAULT, effectively Profile.EDGE, to establish common use case defaults, after which, any number of setter methods may be invoked to further tune the desired configuration state. | | | | |
< < | Lastly, the provided constructor arguments are accessed accordingly. None of the Configurator constructors throw exceptions so creating a new instance is relatively ensured. The principal constructors are as follows: | > > | During instantiation, existing PlatformConfig and profile.xml references are processed in order to implement "configuration update" support. Existing PlatformConfig instances are given ultimate preference in this regard. Lastly, the provided constructor arguments are processed accordingly and serve to overlay the current state. None of the Configurator constructors throw exceptions at this time so generating a Configurator instance is ensured. | | | | |
< < |
- Configurator(String name, String password)
- Configurator(Profile)
- Configurator(PlatformConfig)
| > > | Generating a PlatformConfig is achieved by invoking getPlatformConfig(): | | | | |
< < | note: Deprecated constructors are not included. In addition, a JXTA_HOME constructor may be added at a future time in order to address the static concern noted above. | > > |
public PlatformConfig getPlatformConfig()
throws ConfiguratorException
| | | | |
< < | The sole objective of the Configurator is to construct a viable PlatformConfig object. To this end there are two primary PlatformConfig generation methods: | > > | Optionally, the derived configuration state can be persisted by invoking save() noting that save() will invoke getPlatformConfig() in the event it has not been invoked directly: | | | | |
< < |
- public PlatformConfig getPlatformConfig() throws ConfiguratorException
- public boolean save() throws ConfiguratorException
- public boolean save(File pc) ConfiguratorException
| > > |
public boolean save()
throws ConfiguratorException
| | | | |
< < | note: The save() method simply invokes save(new File(getHome(), "PlatformConfig")) | > > | The ConfiguratorException object chains all causal exceptions which are in turn accessible via respective iterators: | | | | |
< < | The ConfiguratorException objects are chained such that all causes are retrievable via respective iterators. | > > |
public List getCauses()
| | | | |
< < | At this point we are now armed with the ability to construct a trivial configurator: | > > | To bring this home, let's construct a trivial Configurator that given the provided peer principal and password will construct and persist a PlatformConfig instance: | | |
import net.jxta.ext.config.Configurator; | | | c.save();
} catch (ConfiguratorException? ce) {
for (Iterator c = ce.getCauses().iterator(); c.hasNext(); ) { | |
< < | Throwable t = (Throwable)c.next();
System.out.println(t.getMesasge());
t.printStackTrace(System.out); | > > | System.out.println(((Throwable)c.next()).getMesasge()); | | | }
}
| |
< < | There you have it. Effectively JXTA configuration accomplished in what amounts to 4 lines of code. Alas, true life is typically not so simple. as such we next turn to the number of Configurator getter/setter methods that provide for ultimate JXTA configuration tuning. Before doing so, let's dive down into the PlatformConfig processing internals a bit. | > > | Alas, life is typically not so simple and as such we move on to explore a number Configurator methods. Before doing so, let's align with the afore mentioned AbstractConfigurator code sample by overriding the default constructor with an alternative working directory and profile, as follows: | | | | |
< < | The save methods actually invoke the getPlatformConfig() method. As such, the only real function of the save() methods are to persist a PlatformConfig, as XML, to the relevant file system. With that, our attention turns back to the getPlatformConfig() method. In short, the following steps are executed in order resulting in either a valid PlatformConfig object or a causal ConfiguratorException exception: | > > |
...
import java.net.URI;
... | | | | |
< < |
- normalization
- optimization
- validation
- PlatformConfig construction
| > > | URI home = new URI(...);
Profile profile = new Profile(...);
Configurator c = new Configurator(home, profile);
...
| | | | |
< < | Taking each of these in turn we start with normalization. Normalization starts out by filling in any blank entries with the relvant defaults. No exceptions or faults are generated during this process. wip: describe address macro expansion | > > | Again, the type of Profile can readily vary during instantiation. Further, you can use Configurator to update an existing PlatformConfig at any time by invoking the setPlatformConfig() method: | | | | |
< < | Next up, the optimizer kicks in by iterating the current and recently normalized Configurator state through all registered Optimizers in succession. wip: detail Optimizer interface, registration | > > |
public void setPlatformConfig(PlatformConfig pc)
| | | | |
< < | Following the resultant Configurator state is exercised against a series of internal heuristics that check for PlatformConfig viability. This process, alone, can throw a ConfiguratorException. | > > | Given Configurator is all encompassing by design and largely a bean (aka property sheet) by implementation the list of setter methods is extensive and but can be broken down into the following categories: | | | | |
< < | Upon passing the validity stage all that remains is PlatformConfig creation whereby the Configurator state is transferred into a representative PlatformConfig instance. | > > |
- peer
- name
- description
- id
- debug
- security (user, password)
- network
- seeding rendezVous
- seeding relays
- services
- transports
</font.
At this time we'll expand on some key members within the configuration family noting that all setters are listed shortly along with a brief description. | | | | |
< < | At this point we should step back and inventory the principal getter/setter methods that are available prior to PlatformConfig generation. Configurator hosts a significantly large number of prototypical getter/setter methods that can be logically grouped as follows: | > > | Peer information including name, working directory and logging information can be specified as follows: | | | | |
< < |
- attributes (eg name, description, id, debug)
- security (user, password)
- services
- RendeZvous
- Relay
- Proxy
- network
- TCP
- HTTP
- others as implemented
- endpoint
- miscellaneous
| > > |
public void setPeerName(String)
public void setJxtaHome(URI) | | | | |
< < | All of the above are invokable but typical use cases call for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile). | > > | public void setTrace(Trace)
| | | | |
< < | Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the *API and *profile, as follows: | > > | The default JXTA network is known as the Public Network (aka PubNet?) which serves as an available testbed network. Specifying a non-default JXTA network is achieved by invoking the "infrastructure group" APIs, which allows one to construct, deploy, operate and scope systems resources to a dedicated network of services: | | | | |
< < | public void setInfrastructurePeerGroupId(PeerGroupID? pgid) | > > | public void setInfrastructurePeerGroupId(PeerGroupID? id) | | | | |
< < | public void setInfrastructurePeerGroupName(String pgnm) | > > | public void setInfrastructurePeerGroupName(String name) | | | | |
< < | public void setInfrastructurePeerGroupDescription(String pgdsc) | > > | public void setInfrastructurePeerGroupDescription(String description) | | | | |
< < | The default "infrastructure peer group" information maps to the PubNet which is great for testing and the like. When specifying a non-default infrastructure peer group you need only provide the PeerGroupID as the name and description attributes are optional. | > > | In order to establish initial JXTA network context it is optimal to specify seeding (aka bootstrap) information after which the peer is free to leverage discovered resources as needed at runtime. Seeding RendezVous and Relays are typical and in fact for "edge" scenarios only the later is required. RendezVous peers serve as a connection resource with which newly instantiated peers can leverage in the form of leases. Relay relationships are established for peers that can not otherwise communicate with one another in a direct fashion which is common for applications running behind corporate firewalls accessing services available on the open internet. These relationships change dynamically as the netork itself changes yet the developer is presented with a unified view of the overall network. A seeding address, be it RendezVous or Relay, takes the form of a fully qualified IP based URI, with examples being: | | | | |
< < | Doing the same via the Profile is evean easier and in many respects preferred: | | | | |
< < |
| > > | tcp://1.2.3.4:9701
http://1.2.3.4:9700
| | | | |
< < |
... | > > | A seeding URI is a simply a resource that returns a list of available seeding addresses as defined above. As such, as seeding URI is often specified with a common domain name, eg:
http://rdv.jxtahosts.net/cgi-bin/rendezvous.cgi?2
http://rdv.jxta.hosts.net/cgi-gin/relays.cgi?2
Any URI is available to use as a seeding URI and need not resolve at runtime to be used. As an example, for standalone development environments a file based URI is optimal, eg:
file:///tmp/rdv.txt
The following methods can be used to specify RendezVous and Relays network resources in addition to whether or not the to be configured peer can leverage newly discovered services:
public void setRendezVousBootstrapAddress(URI)
public void setRendezVous(URI)
public void addRendezVous(URI)
public void setRendezVous(List)
public void setRendezVousDiscovery(boolean)
public void setRelayBootstrapAddress(URI)
public void setRelays(URI)
public void addRelays(URI)
public void setRelays(List)
public void setRelaysDiscovery(boolean) | | | | |
> > | For some network deployments, it can be optimal to restrict "edge" peers from leasing against unknown peers that happen to be provisioning RendezVous and/or Relays services.
Your peer's physical address(es) are utilized to establish bidirectional communications over existing and supported networking protocols. By default, the application's local IP address is used being specified as the Any/All address (e.g. IPv6 "::" or IPv4 "0.0.0.0"). You can specify an explicit address by constructing a Transport instance. Further, for configurations where the actual system IP is not resolvable by all (e.g. NAT) you can specify the public address and opt to keep the internal and unresolvable by many address private. The following code sample constructs just such a configuration:
import net.jxta.ext.config.MulticastAddress;
import net.jxta.ext.config.TcpTransport;
import net.jxta.ext.config.TcpTransportAddress;
import java.net.URISyntaxException;
...
TcpTransportAddress ta = new TcpTransportAddress();
try {
ta.setAddress(new URI("tcp://1.2.3.4:9701"));
} catch (URISyntaxException use) {
...
}
try {
ta.set
} catch (URISyntaxException use) {
...
}
MulticastAddress ma = new MulticastAddress();
ma.setMulticast(true);
try {
ma.setAddress(new URI("udp://4.3.2.1:1079"));
} catch (URISyntaxException use) {
...
}
ta.setMulticastAddress(ma);
PublicAddress pa = new PublicAddress();
pa.setExclusive(true);
try {
pa.setAddress(new URI("tcp://10.20.30.40:9701"));
} catch (URISyntaxException use) {
...
}
TcpTransport tt = new TcpTransport();
tt.setAddress(ta);
tt.setPublicAddress(pa);
c.setTransport(tt);
It should be noted that doing the equivalent using only Profile constructs is significantly more intuitive and less prone to error. We will touch on this topic shortly. Till then, with a Transport object in hand, we can augment the configuration state via the following methods:
public void setTransport(Transport)
public void addTransport(Transport)
public void addTransports(List)
public void setTransports(List)
Following is a terse overview of the configuration attribute setters followed by a brief narrative presented in tabular form:
| method | description |
| setDescriptor(String) | configuration descriptor |
| setName(String) | peer name |
| setDescription(String) | peer description |
| setTrace(Trace) | log level |
| setPeerId(PeerID) | peer id |
| setRendezVous(boolean) | rendezVous service enabled |
| setRendezVous(URI) | seeding rendezVous address |
| addRendezVous(URI) | add seeding rendezVous address |
| setRendezVous(List) | seeding rendezVous addresses |
| addRendezVous(List) | add seeding rendezVous addresses |
| setRendezVousAutosStart(long) | auto rendezVous attribute |
| setRelay(boolean) | relay service enabled |
| setRelay(URI) | seeding relay address |
| addRelay(URI) | add seeding relay address |
| setRelay(List) | seeding relaly addresses |
| addRelays(List) | add seeding relaly addresses |
| setRelayIncoming(boolean) | relay client |
| setRelayIncomingMaximum(int) | maximum server lease support |
| setRelayIncomingLease(long) | server lease duration |
| setRelayOutgoing(boolean) | relay server |
| setRelayOutgoingMaximum(int) | maximum client lease support |
| setRelayOutgoingLease(long) | client lease duration |
| setRelayQueueSize(int) | relay queue |
| setTransport(Transport) | physical address |
| addTransport(Transport) | add physical address |
| addTransports(List) | add physical addresses |
| setTransports(List) | physical addresses |
| setSecurity(boolean) | security is enabled |
| setSecurity(String, String) | security principal and password |
| setRootCertificateAddress(URI) | root certificate address |
| setRootCertificate(Certificate) | root certificate |
| setRootCertificateBase64(String) | root certificate as Base64 |
| setPeerProxyAddress(URI) | proxy peer |
| setEndpointOutgoingQueueSize(int) | endpoint queue capacity |
| setProxy(boolean) | proxy service enabled |
| setInfrastructurePeerGroupId(PeerGroupID?) | infrastructure network id |
| setInfrastructurePeerGroupName(String) | infrastructure group name |
| setInfrastructurePeerGroupDescription(String) | infrastructure group description |
| setRendezVousBootstrapAddress(URI) | seeding address |
| setRendezVousDiscovery(boolean) | directs leasing from discovered rendezVous peers |
| setRelaysBootstrapAddress(URI) | seeding address |
| setRelaysDiscovery(boolean) | directs leasing from discovered relay peers |
| setPlatformConfig(PlatformConfig) | basis for configuration state |
| setConfigParams(ConfigParams?) | basis for configuration state |
| setReconfigure(booleans) | reconfiguration upon start indicator |
| addOptimizer(Optimizer) | add optimizer |
| addOptimizers(List) | add optimizers |
While all of the above methods are readily invokable, common practice is to instantiate a Configurator from a baseline profile and only invoke the few remaining setters of specific interest.
The save methods actually invoke the getPlatformConfig() method. As such, the only real function of the save() methods are to persist a PlatformConfig, as XML, to the relevant file system. With that, our attention turns back to the getPlatformConfig() method. In short, the following steps are executed in order resulting in either a valid PlatformConfig object or a causal ConfiguratorException exception:
- normalization
- optimization
- validation
- PlatformConfig construction
Taking each of these in turn we start with normalization. Normalization starts out by filling in any blank entries with the relvant defaults. No exceptions or faults are generated during this process. wip: describe address macro expansion
Next up, the optimizer kicks in by iterating the current and recently normalized Configurator state through all registered Optimizers in succession. wip: detail Optimizer interface, registration
Following the resultant Configurator state is exercised against a series of internal heuristics that check for PlatformConfig viability. This process, alone, can throw a ConfiguratorException. | | |
Profile (aka ext:config/profile) |
|
<<O>> Difference Topic
ExtConfig
(9 - 21 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
| |
< < | ext:config - flexible JXTA configuration with ease. | > > | ext:config : extensible JXTA configuration with ease. | | | Table of Contents | | | Abstract | |
< < | The ext:config API is an optional JXTA extension that both eases and extends the core JXTA configuration principals. This is achieved through the combination of a comprehensive API implemented with optimal defaults encompassed with optional declarative models and UI constructs. | > > | The ext:config library is an optional JXTA extension that both eases and extends the core JXTA configuration principals. This is achieved through the combination of a comprehensive bean API that is backed with common use-case defaults in addition to declarative preset support and UI utilities, all of which progressively build upon one another and are in part or in full optional. | | | | |
< < | The principal ext:config constituents are: | > > | Each of the following ext:config principals will be discussed in detail: | | | | | | Dependencies | |
< < | At present, the required ext:config jars are the following: | > > | The required ext:config jars are the following: | | | | | |
-
- jdom.jar (required only for UI)
- swixml.jar (required only for UI)
| |
< < | These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section. | > > | These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section. | | | Introduction | |
< < | For the most part, JXTA applications are typically self configuring, taking as an exammple sample reference applications that act largely as "service consumers" by connecting to pre-existing JXTA networks. Saying that, some applications can benefit from fine tuning, augmenting and extending core JXTA configurations and this is the principal role of ext:config. | > > | JXTA applications are typically self configuring. This is due in part to the JXTA design principal that peers actively seek to leverage discovered services and in part due to the wide domain upon which JXTA applications are deployed, collectively resulting in the need for autonomous configuration. In the first case, the application's role is largely that of a "service consumer" by connecting to existing JXTA networks and associated provisioned resources. On the other hand, some applications can benefit from fine tuning, augmenting and extending core JXTA configuration parameters. | | | | |
< < | JXTA configuration information can be persisted in the form of a PlatformConfig object. Typically, for file based applications, a PlatformConfig file is resident in the relative JXTA_HOME directory before the JXTA Platform starts up. As such, JXTA configuration is a runtime precondition. | > > | ext:config's role is to make \uffffeasy things trivial and all things possible.\uffff As such, ext:config can be leveraged to seamlessly construct, update, extend, validate, optimize and integrate JXTA configuration processes as best suited for the hosting application. | | | | |
< < | ext:config can be leveraged to construct, update, validate, extend, optimize and integrate JXTA configuration processes as best suited for the hosted application. ext:config is comprised of three principal domains: | > > | Principal JXTA configuration information is collected the form of a PlatformConfig object. For file based persistent environments, a PlatformConfig XML file often resides within the application's specified working directory, aka JXTA HOME, as a JXTA Platform start up precondition. In memory only application environments as well as runtime configuration support is also available and is actively under development. | | | | |
< < |
- API
- Profile
- User Interface
The ext:config/api library is principally a traditional API with which one can construct, manipulate and obtain a valid JXTA configuration. The basic design of ext:config/api is largely that of "property sheet" as it provides a series of getter and setter methods, for the most part. The most important classes in ext:config/api are AbstractConfigurator and Configurator. | > > | The ext:config/api library is principally a bean or property sheet styled API with which one can construct, manipulate and generate a valid JXTA configuration in the form of a PlatformConfig object. The principal classes in ext:config/api are AbstractConfigurator and Configurator. | | | | |
< < | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles." The most important class in ext:config/profile is Profile. | > > | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles" which are largely configuration presets. The principal class in in ext:config/profile is *net.jxta.ext.config. | | | | |
< < | The ext:config/ui provides a means to present user interface elements to manage JXTA configuration processes. ext:config/ui drives ext:config/profile. | > > | The ext:config/ui provides a series of user interface elements to manage JXTA configuration data. | | |
API (aka ext:config) | |
< < | The ext:config API is the core of the ext:config package with both the Profile and UI tiers layering above, in succession. A Configurator provides the ability instantiate and persist JXTA configuration state based upon declarative Profile and PlatformConfig information.
A Configurator serves primarily as a JXTA Configuration Bean, or property sheet, and implements very little attribute association logic beyond that of what is required to perform fundamental configuration integrity validation. | > > | The ext:config API is the core of the ext:config package with both the Profile and UI tiers layering above, in succession. A Configurator provides the ability instantiate and persist JXTA configuration state based upon the provided information and applied heuristics. The Configurator serves primarily as a JXTA Configuration Bean, or property sheet, and as such implements very little attribute association logic beyond that of what is required to perform fundamental configuration integrity validation. | | | The principal constituents of a JXTA Configurator are:
| |
> > | | | |
- Peer Transports
- Peer Services
| |
< < | | | | | |
< < | Peer Information describes the local JXTA instance that a specified Configurator instance represents. The bulk of the Peer Information configuration data is optional and includes: | > > | Peer Information describes the local JXTA instance that a specified Configurator instance represents. The bulk of the peer information configuration data is optional and includes: | | | | | |
- root certificate
- HTTP Proxy
| |
< < | Peer Transports describe the physical Address with which a Peer connects with the overall JXTA Network. Transports can be specified as incoming (aka server), outgoing (aka client) and both. Transport implementations include: | > > | The JXTA Network information specifies JXTA Network Services upon which the to be instantiated peer will leverage as initialing seeding (aka bootstrap) information:
- Network
- RendezVous
- Relays
Peer Transports describe the physical address and transports with which a peer connects to the greater JXTA Network. Transports can be specified as incoming (aka server), outgoing (aka client) and both. Transport implementations include: | | | | |
< < | Peer Services represent the JXTA Services that a specified Configurator instance will provision, which include: | > > | Peer Services represent the JXTA Services that the to be instantiated peer will provision, which include: | | | | |
< < | The JXTA Network information specifies JXTA Network Services upon which a specified Configurator instance will rely upon, including:
- Network
- RendezVous
- Relays
The Configuration Extensions information includes extensible configuration features that includes end user provided Optimizer. | > > | The Configuration Extensions information includes extensible configuration features such as end user provided Optimizer implementations: | | | The principal API classes are:
- net.jxta.ext.config.AbstractConfigurator
- net.jxta.ext.config.Configurator
| |
< < | A number of supporting classes are also available that aid in the configuration management process. | > > | A number of supporting classes are also available that aid in the overall configuration management process. | | | | |
< < | The primary ext:config class a developer will use is AbstractConfigurator. This class implements the JXTA PlatformConfigurator interface and includes one abstract method: | > > | The easiest means to leverage the ext:config API is to implement an AbstractConfigurator by implementing the singular abstract createPlatformConfig() method. This method is invoked during the configuration lifecylce when either a PlatformConfig object does not exist or is invalid. The method signature is as follows: | | |
public abstract PlatformConfig createPlatformConfig(PlatformConfigurator configurator)
throws ConfiguratorException;
| |
< < | As such, the following is a complete JXTA configurator minus the requisite application specify configuration details: | > > | With this in mind, following is a complete AbstractConfigurator implementation, assuming some hardwired values for the time being: | | |
import net.jxta.ext.config.AbstractConfigurator; | | |
import net.jxta.ext.config.AbstractConfigurator;
import net.jxta.ext.config.Configurator; | |
< < | | | | import net.jxta.exception.ConfiguratorException; | |
< < | import net.jxta.impl.peergroup.PlatformConfigurator; | | | import net.jxta.impl.protocol.PlatformConfig;
public class MyConfigurator?
extends AbstractConfigurator? { | |
< < | public PlatformConfig createPlatformConfig(Configurator pc) | > > | public PlatformConfig createPlatformConfig(Configurator c) | | | throws ConfiguratorException? { | |
< < | // xxx: application specific configuration logic | > > | c.setName("name");
c.setSecurity("principal", "password"); | | | return c.getPlatformConfig();
}
}
| |
< < | In order to manipulate the configuration process during each and every startup one can override the updatePlatformConfig(PlatformConfigurator) method: | > > | In order to perform configuration changes during each configuraiton cycle configuration the provided updatePlatformConfig() method can be overridden: | | |
public PlatformConfig updatePlatformConfig(PlatformConfigurator configurator) | |
< < | throws ConfiguratorException? | > > | throws ConfiguratorException? {
...
} | | | | |
< < | The corresponding AbstractConfigurator implementation is thusly invoked prior to JXTA Platform start up.
Once an AbstractConfigurator instance has been instantiated, invoking the configure method will result, baring exceptions, in either a newly created or updated JXTA configuration: | > > | Lastly, the configure() method can be invoked to trigger the configuration life cycle: | | |
public PlatformConfig configure() | |
< < | throws ConfiguratorException? ... | > > | throws ConfiguratorException? {
...
} | | | | |
< < | Rollling all of this information together, the following code snippet represents a practical application of AbstractConfigurator that performs the following tasks:
- specifies a JXTA_HOME attribute
- specifies the systems property JXTA_HOME (needed for the JXTA platform)
- specifies the prototypical "edge" profile
- create the JXTA configuration derivatives specifing configuration security parameters
- invoke the default update logic
- start the JXTA platform
| > > | The derived PlatformConfig can be used to immediately instantiate a peer or passed along to another process as is. With that in mind, a comprehensive code example is as follows: | | | | |
< < | ... | | | import net.jxta.ext.config.AbstractConfigurator;
import net.jxta.ext.config.Configurator; | |
< < | import net.jxta.ext.config.Profile; | | | import net.jxta.exception.ConfiguratorException; | |
< < | import net.jxta.impl.protocol.PlatformConfig; | | | import net.jxta.exception.PeerGroupException; | |
> > | import net.jxta.impl.protocol.PlatformConfig; | | | import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory; | |
< < | import java.net.MalformedURLException;
import java.net.URL; | | | ... | |
< < | PeerGroup npg = null;
URL jh = null;
// specify a JXTA_HOME
try {
jh = new URL("file:///path/to/jxta/home");
} catch (MalformedURLException mue) {
mue.printStackTrace();
}
if (jh = null) {
// system property JXTA_HOME required before invoking the JXTA platform (at this time)
System.setProperty(JXTA_HOME, jh.getPath());
try {
// AbstractConfigurator? specified with the JXTA_HOME and prototypical Profile
new AbstractConfigurator?(jh, Profile.EDGE) { | > > | AbstractConfigurator? c = new AbstractConfigurator?() { | | | public PlatformConfig createPlatformConfig(Configurator c)
throws ConfiguratorException? { | |
< < | // specify configuration security parameters | | | c.setName("name"); | |
< < | c.setSecurity("name", "password"); | > > | c.setSecurity("principal", "password"); | | | return c.getPlatformConfig();
} | |
< < | }).configure(); | > > | } | | | | |
< < | // start the JXTA platform
this.npg = PeerGroupFactory?.newNetPeerGroup();
} catch (ConfiguratorException? ce) {
ce.printStackTrace(); | > > | PeerGroup npg = null;
try {
c.configure();
npg = PeerGroupFactory?.newNetPeerGroup(...);
} catch(ConfigurationException? ce) {
... | | | } catch (PeerGroupException? pge) { | |
< < | pge.printStackTrace();
} | > > | ... | | | }
| |
< < | You can readily provide your own specialized Profile by changing the AbstractConfigurator constructor as follows: | > > | The above code will perform the following actions:
- create the default "./.jxta" working directory if it doesn't exist
- read the ./.jxta/PlatformConfig file in the specified home
- read the ./.jxta/profile.xml file in the specified home
- create and return a PlatformConfig
The information used to initialize the AbstractConfigurator instance can be influenced by a number optional constructors, including:
- no-arg
- URI representing the working directory (aka JXTA Home)
- Profile
- alternative backing Configurator delegate
Typical usage is to override the defaults by specifying an application specific working home (aka JXTA HOME) and application specific Profile:
...
import net.jxta.ext.config.Profile
import java.net.URI;
...
URI home = new URI(...);
Profile profile = new Profile(...);
AbstractConfigurator c = new AbstractConfigurator(home, profile) {
In addition to the above mentioned processes, the above code will:
- create and/or read the specified working directory
- reference the specified profile
Barring exceptions, one can then instantiate a JXTA Platform by referencing the derived JXTA Home and it's included artificats, namely PlatformConfig.
A future release of JXTA (see Platform 2.3.7 + patches 1488 and 1500) will enable one to efficiently configure and start a peer instance in addition to optionally persisting the configuration artifacts: | | | | |
< < | URL ph = null; | > > | ...
//import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.peergroup.NetPeerGroupFactory;
... | | | | |
< < | // specify a profile | | | try { | |
< < | ph = new URL("file:///path/to/jxta/profile.xml");
} catch (MalformedURLException mue) {
mue.printStackTrace(); | > > | // c.confgure();
//
// npg = PeerGroupFactory?.newNetPeerGroup(...);
npg = NetPeerGroupFactory?(c.configure(), c.getJxtaHome());
c.save();
} catch (ConfiguratorException? ce) {
...
} catch (PeerGroupException? pge) {
... | | | } | |
> > |
We'll touch on the different types of Profiles shortly but that aside for a moment now is a good time to mention that you can trivially vary the profile used by your AbstractConfigurator implementation via it's constructor, as follows:
...
//Profile profile = new Profile(...);
AbstractConfigurator c = new AbstractConfigurator(home, Profile.EDGE) {
//AbstractConfigurator c = new AbstractConfigurator(home, Profile.SUPER) {
...
Further, you can readily instantiate a specialized applications specific profile as follows: | | | | |
< < | // new AbstractConfigurator?(jh, Profile.EDGE) {
new AbstractConfigurator?(jh, ph) { | > > |
...
URI profile = getClass().getResourceAsStream("/path/to/my/profile.xml");
AbstractConfigurator c = new AbstractConfigurator(home, new Profile(profile)) {
... | | | | |
< < | A number of resource management APIs exist which serve to transfer named resources into the resulting JXTA working directory. Resources can be of any form and are accessed via unique names which, in turn, are mapped to file names hosted under the afore mentioned directory. This way, a developer can scope application data to distinct application instances. | > > | AbstractConfigurator can be used as a PlatformConfig factory, e.g. cluster configuration generation, by simply invoking the getPlatformConfig() method:
public PlatformConfig getPlatformConfig()
throws ConfiguratorException {
| | | | |
< < | Following is a resource management example derived from MyJXTA: | > > | As as application developer convenience, named resources can be registered which will be deposited in the working directory. A common use for these APIs is to scope your applications data repository to the running JXTA instance. | | | | |
> > | ...
AbstractConfigurator? c = new AbstractConfigurator?() {
{ | | | addResource(PROFILE_KEY, "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml"); | |
> > | }
public PlatformConfig createPlatformConfig(Configurator c)
throws ConfiguratorException? {
... | | | | |
< < | With an AbstractConfigurator implementation in hand we can now turn to the principal configuration class, aptly named Configurator. | > > | Before we move on to the next topic, let's recap the AbstractConfigurator life cycle: | | | | |
< < | The Configurator class serves to programatically create new and update existing PlatformConfig instances. As mentioned above, a Configurator can be managed via the AbstractConfigurator class or used standalone. For runtime environements, use of the AbstractConfigurator is encouraged as much of the file systems mechanics et al are managed by the ext:config framework. On the other hand, Configurator can be used to generate PlatformConfig objects for use elsewhere such as cluster configuration. | > > |
- instantiation
- optionally specifying
- working directory
- profile
- configuration delegate
- implement createPlatformConfig() for new PlatformConfig generation
- optionally implement updatePlatformConfig() for PlatformConfig updates
- create a PlatformConfig
- invoke configure to create and persist a PlatformConfig
- invokes createPlatformConfig()
- inovkes updatePlatformConfig()
- (ed: subject to change) invokes save()
- or invoke getPlatformConfig() to create a PlatformConfig
- invokes createPlatformConfig()
- inokes updatePlatformConfig()
When implementing AbstractConfigurator createPlatformConfig() and updatePlatformConfig() methods you will work directly with the underlying configuration delegate, aptly named Configurator. With that, we turn our attention to the Configurator API.
The Configurator class serves to programmatically create new or update existing PlatformConfig instances by managing all configuration attributes in addition to performing data integrity and optional data optimizations. As mentioned above, a Configurator is most often managed via an AbstractConfigurator implementation although it can just as easily be used as a standalone component. | | | The lifecycle of a Configurator is typically quite short. Initially, a few key static constructs are invoked in order to establish a baseline Configurator instance. Firstly, a default PlatformConfig object is processed followed by the protected Profile.SEED profile. Lastly, the default JXTA_HOME is set to the .jxta directory hosted in the user's home directory, programmactically as follows: | | | All of the above are invokable but typical use cases call for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile). | |
< < | Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the API and profile, as follows: | > > | Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the *API and *profile, as follows: | | |
public void setInfrastructurePeerGroupId(PeerGroupID pgid) | | | public void setInfrastructurePeerGroupDescription(String pgdsc)
| |
< < | The default "infrastructure peer group" information maps to the PubNet which is great for testing and the like. When specifying a non-default infrastructure peer group you need only provide the PeerGroupID as the name and description attributes are optional.
Doing the same via the Profile is evean easier and in many respects preferred: | > > | The default "infrastructure peer group" information maps to the PubNet which is great for testing and the like. When specifying a non-default infrastructure peer group you need only provide the PeerGroupID as the name and description attributes are optional. | | | | |
> > | Doing the same via the Profile is evean easier and in many respects preferred: | | |
<jxta>
<peer descriptor="my net edge"/> |
|
<<O>> Difference Topic
ExtConfig
(8 - 16 Mar 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease. | | | | |
< < |
-
- jdom.jar (pending removal, see #1453)
- jaxen.jar (pending removal, see #1453)
- jaxen-jdom.jar (pending removal, see #1453)
- saxpath.jar (pending removal, see #1453)
| > > |
-
- jdom.jar (required only for UI)
| | |
-
- swixml.jar (required only for UI)
These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section. | | | The JXTA Network information specifies JXTA Network Services upon which a specified Configurator instance will rely upon, including: | |
< < | | > > | | | | | | | throws ConfiguratorException?;
| |
< < |
ed: remove
AbstractConfigurator implementations are notified via the createPlatformConfig(PlatformConfigurator) during JXTA Platform startup process when configuration data is required either as missing or incomplete. It is at this time applications can inject configuration details into the process.
| | | As such, the following is a complete JXTA configurator minus the requisite application specify configuration details: | | | }
| |
< < |
ed: remove
In order to override the default JXTA Platform configuration process you register your AbstractConfigurator implementation with the Platform as the configuration delegate:
MyConfigurator.register(MyConfigurator.class);
| | | In order to manipulate the configuration process during each and every startup one can override the updatePlatformConfig(PlatformConfigurator) method: | | | The corresponding AbstractConfigurator implementation is thusly invoked prior to JXTA Platform start up. | |
< < | | | | Once an AbstractConfigurator instance has been instantiated, invoking the configure method will result, baring exceptions, in either a newly created or updated JXTA configuration: | | | // new AbstractConfigurator?(jh, Profile.EDGE) {
new AbstractConfigurator?(jh, ph) {
| |
< < | | | | A number of resource management APIs exist which serve to transfer named resources into the resulting JXTA working directory. Resources can be of any form and are accessed via unique names which, in turn, are mapped to file names hosted under the afore mentioned directory. This way, a developer can scope application data to distinct application instances.
Following is a resource management example derived from MyJXTA: | |
< < |
ed: remove
addResource("profile.xml", "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| | |
addResource(PROFILE_KEY, "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| |
< < | With an AbstractConfigurator implementation in hand (ed: remove) and registered with the JXTA Platform as the configuration delegate we can now turn to the principal configuration class, aptly named Configurator. | > > | With an AbstractConfigurator implementation in hand we can now turn to the principal configuration class, aptly named Configurator. | | | The Configurator class serves to programatically create new and update existing PlatformConfig instances. As mentioned above, a Configurator can be managed via the AbstractConfigurator class or used standalone. For runtime environements, use of the AbstractConfigurator is encouraged as much of the file systems mechanics et al are managed by the ext:config framework. On the other hand, Configurator can be used to generate PlatformConfig objects for use elsewhere such as cluster configuration. | | | All of the above are invokable but typical use cases call for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile). | |
< < |
Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the API and profile, as follows: | > > | Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the API and profile, as follows: | | |
public void setInfrastructurePeerGroupId(PeerGroupID pgid) | | |
...
| |
< < | | | |
Profile (aka ext:config/profile) | | |
- JXTA jar dependencies
- Daniel Brookshier's Autoconfig example?
| |
< < | -- JamesTodd - 01 Feb 2005 | > > | -- JamesTodd - 01 Feb 2005
| | | -- updated.RayGao - 21, Nov. 2005 |
|
<<O>> Difference Topic
ExtConfig
(7 - 12 Jan 2006 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease. | | | | |
< < | The ext:config/api library is principally a traditional API with which one can construct, manipulate and obtain a valid JXTA configuration. The basic design of ext:config/api is largely that of "property sheet" as it provides a series of getter and setter methods, for the most part. The most important classes in ext:config/api are AbstractConfigurator? and Configurator. | > > | The ext:config/api library is principally a traditional API with which one can construct, manipulate and obtain a valid JXTA configuration. The basic design of ext:config/api is largely that of "property sheet" as it provides a series of getter and setter methods, for the most part. The most important classes in ext:config/api are AbstractConfigurator and Configurator. | | | The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles." The most important class in ext:config/profile is Profile. | | | The JXTA Network information specifies JXTA Network Services upon which a specified Configurator instance will rely upon, including: | |
> > | | | | | | | throws ConfiguratorException?;
| |
> > |
ed: remove | | | AbstractConfigurator implementations are notified via the createPlatformConfig(PlatformConfigurator) during JXTA Platform startup process when configuration data is required either as missing or incomplete. It is at this time applications can inject configuration details into the process. | |
> > | | | | As such, the following is a complete JXTA configurator minus the requisite application specify configuration details:
import net.jxta.ext.config.AbstractConfigurator; | |
> > | import net.jxta.ext.config.Configurator; | | | import net.jxta.exception.ConfiguratorException;
import net.jxta.impl.peergroup.PlatformConfigurator; | | | public class MyConfigurator?
extends AbstractConfigurator? { | |
< < | public PlatformConfig createPlatformConfig(PlatformConfigurator? pc) | > > | public PlatformConfig createPlatformConfig(Configurator pc) | | | throws ConfiguratorException? {
// xxx: application specific configuration logic | |
< < | return pc.getPlatformConfig(); | > > | return c.getPlatformConfig(); | | | }
}
| |
> > |
ed: remove | | | In order to override the default JXTA Platform configuration process you register your AbstractConfigurator implementation with the Platform as the configuration delegate:
MyConfigurator.register(MyConfigurator.class);
| |
> > | | | | In order to manipulate the configuration process during each and every startup one can override the updatePlatformConfig(PlatformConfigurator) method: | | | throws ConfiguratorException?
| |
< < | The corresponding AbstractConfigurator implementation is thusly notified each time just prior to JXTA Platform start up. | > > | The corresponding AbstractConfigurator implementation is thusly invoked prior to JXTA Platform start up.
Once an AbstractConfigurator instance has been instantiated, invoking the configure method will result, baring exceptions, in either a newly created or updated JXTA configuration:
public PlatformConfig configure()
throws ConfiguratorException ...
Rollling all of this information together, the following code snippet represents a practical application of AbstractConfigurator that performs the following tasks:
- specifies a JXTA_HOME attribute
- specifies the systems property JXTA_HOME (needed for the JXTA platform)
- specifies the prototypical "edge" profile
- create the JXTA configuration derivatives specifing configuration security parameters
- invoke the default update logic
- start the JXTA platform
...
import net.jxta.ext.config.AbstractConfigurator;
import net.jxta.ext.config.Configurator;
import net.jxta.ext.config.Profile;
import net.jxta.exception.ConfiguratorException;
import net.jxta.impl.protocol.PlatformConfig;
import net.jxta.exception.PeerGroupException;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import java.net.MalformedURLException;
import java.net.URL;
...
PeerGroup npg = null;
URL jh = null;
// specify a JXTA_HOME
try {
jh = new URL("file:///path/to/jxta/home");
} catch (MalformedURLException mue) {
mue.printStackTrace();
}
if (jh != null) {
// system property JXTA_HOME required before invoking the JXTA platform (at this time)
System.setProperty(JXTA_HOME, jh.getPath());
try {
// AbstractConfigurator specified with the JXTA_HOME and prototypical Profile
new AbstractConfigurator(jh, Profile.EDGE) {
public PlatformConfig createPlatformConfig(Configurator c)
throws ConfiguratorException {
// specify configuration security parameters
c.setName("name");
c.setSecurity("name", "password");
return c.getPlatformConfig();
}
}).configure();
// start the JXTA platform
this.npg = PeerGroupFactory.newNetPeerGroup();
} catch (ConfiguratorException ce) {
ce.printStackTrace();
} catch (PeerGroupException pge) {
pge.printStackTrace();
}
}
You can readily provide your own specialized Profile by changing the AbstractConfigurator constructor as follows:
URL ph = null;
// specify a profile
try {
ph = new URL("file:///path/to/jxta/profile.xml");
} catch (MalformedURLException mue) {
mue.printStackTrace();
}
// new AbstractConfigurator(jh, Profile.EDGE) {
new AbstractConfigurator(jh, ph) {
| | | A number of resource management APIs exist which serve to transfer named resources into the resulting JXTA working directory. Resources can be of any form and are accessed via unique names which, in turn, are mapped to file names hosted under the afore mentioned directory. This way, a developer can scope application data to distinct application instances.
Following is a resource management example derived from MyJXTA: | |
> > |
ed: remove | | |
addResource("profile.xml", "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| |
< < | note: see #1449 | > > | | | |
addResource(PROFILE_KEY, "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| |
< < | With an AbstractConfigurator implementation in hand and registered with the JXTA Platform as the configuration delegate we now turn to the principal configuration class, aptly named Configurator. | > > | With an AbstractConfigurator implementation in hand (ed: remove) and registered with the JXTA Platform as the configuration delegate we can now turn to the principal configuration class, aptly named Configurator. | | | The Configurator class serves to programatically create new and update existing PlatformConfig instances. As mentioned above, a Configurator can be managed via the AbstractConfigurator class or used standalone. For runtime environements, use of the AbstractConfigurator is encouraged as much of the file systems mechanics et al are managed by the ext:config framework. On the other hand, Configurator can be used to generate PlatformConfig objects for use elsewhere such as cluster configuration. | | |
- endpoint
- miscellaneous
| |
< < | All of the above are invokable but typical use case calls for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile). | > > | All of the above are invokable but typical use cases call for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile).
Having the ability to deploy one's own "private" JXTA network, in order to scope systems resources to a specific application family, perform testing or some such similiar function, is a common requirement. ext:config supports such deployments via both the API and profile, as follows:
public void setInfrastructurePeerGroupId(PeerGroupID pgid)
public void setInfrastructurePeerGroupName(String pgnm)
public void setInfrastructurePeerGroupDescription(String pgdsc)
The default "infrastructure peer group" information maps to the PubNet which is great for testing and the like. When specifying a non-default infrastructure peer group you need only provide the PeerGroupID as the name and description attributes are optional.
Doing the same via the Profile is evean easier and in many respects preferred:
<jxta>
<peer descriptor="my net edge"/>
<network id="urn:jxta:uuid-1989101400200008151800200509221502">
...
| | |
Profile (aka ext:config/profile) | | |
| | security | | | | |
| | proxy | | | | |
| network | subscribed services | | | | |
| |
> > |
| | id | network peer group id | | | |
| | name | network name | | | |
| | description | network description | | | |
| | |
| | rendezVous | subscribed rendezVous services | | | |
| | | bootstrap | seeding URL | | |
| | | discovery | disallow usage of discovered rendezVous | | |
| | | Following are the steps necessary to compile and run the included functional code samples. The prerequisites are: | |
< < |
- J2SE (1.5 recommended0
| > > |
- J2SE (1.5 recommended)
| | |
- Ant
Obtain a working copy of the ext-config-lab.zip code samples and uncompress it accordingly followed by changing your working directory to that of the top-level jxta directory provided by the distribution. Running Ant with no arguments will display the usage message: |
|
<<O>> Difference Topic
ExtConfig
(6 - 21 Nov 2005 - Main.raygao)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease. | | | UI (aka ext:config/ui)
Lastly, the ext:config/ui tier provides an extensible UI above the afore mentioned ext:config/profile tier. | |
> > | It is done in the manner of Swing (Event model) with xxxModels and xxxListeners. see JXTA ext:UI doc for detail. | | | wip ... | | |
- Daniel Brookshier's Autoconfig example?
-- JamesTodd - 01 Feb 2005 | |
> > | -- updated.RayGao - 21, Nov. 2005 | | | |
|
<<O>> Difference Topic
ExtConfig
(5 - 02 Nov 2005 - Main.gonzo)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease. | | | | |
< < |
-
- jdom.jar
- jaxen.jar
- jaxen-jdom.jar
- saxpath.jar
note: work is underway to replace the afore mentioned 3rd party jars with the JAXP 1.3 equivalent at which time for JRE 1.5 runtimes will require no extra jars and JRE 1.4 runtimes will require only 1 extra jar. | > > |
-
- jdom.jar (pending removal, see #1453)
- jaxen.jar (pending removal, see #1453)
- jaxen-jdom.jar (pending removal, see #1453)
- saxpath.jar (pending removal, see #1453)
- swixml.jar (required only for UI)
| | | These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section. | |
> > | Introduction
For the most part, JXTA applications are typically self configuring, taking as an exammple sample reference applications that act largely as "service consumers" by connecting to pre-existing JXTA networks. Saying that, some applications can benefit from fine tuning, augmenting and extending core JXTA configurations and this is the principal role of ext:config.
JXTA configuration information can be persisted in the form of a PlatformConfig object. Typically, for file based applications, a PlatformConfig file is resident in the relative JXTA_HOME directory before the JXTA Platform starts up. As such, JXTA configuration is a runtime precondition.
ext:config can be leveraged to construct, update, validate, extend, optimize and integrate JXTA configuration processes as best suited for the hosted application. ext:config is comprised of three principal domains:
- API
- Profile
- User Interface
The ext:config/api library is principally a traditional API with which one can construct, manipulate and obtain a valid JXTA configuration. The basic design of ext:config/api is largely that of "property sheet" as it provides a series of getter and setter methods, for the most part. The most important classes in ext:config/api are AbstractConfigurator? and Configurator.
The ext:config/profile is a declarative means to manage JXTA configuration processes by driving the afore mentioned ext:config/api via "profiles." The most important class in ext:config/profile is Profile.
The ext:config/ui provides a means to present user interface elements to manage JXTA configuration processes. ext:config/ui drives ext:config/profile. | | |
API (aka ext:config) | |
< < | The ext:config API is the core of the ext:config package with both the profile and ext:config/ui tiers layering above, in succession. The principal API clases are: | > > | The ext:config API is the core of the ext:config package with both the Profile and UI tiers layering above, in succession. A Configurator provides the ability instantiate and persist JXTA configuration state based upon declarative Profile and PlatformConfig information.
A Configurator serves primarily as a JXTA Configuration Bean, or property sheet, and implements very little attribute association logic beyond that of what is required to perform fundamental configuration integrity validation.
The principal constituents of a JXTA Configurator are:
- Peer Information
- Peer Transports
- Peer Services
- JXTA Network
- Configuration Extensions
Peer Information describes the local JXTA instance that a specified Configurator instance represents. The bulk of the Peer Information configuration data is optional and includes:
- name
- ID
- descriptor
- JXTA Home
- Log4J trace level
- security
- root certificate
- HTTP Proxy
Peer Transports describe the physical Address with which a Peer connects with the overall JXTA Network. Transports can be specified as incoming (aka server), outgoing (aka client) and both. Transport implementations include:
Peer Services represent the JXTA Services that a specified Configurator instance will provision, which include:
The JXTA Network information specifies JXTA Network Services upon which a specified Configurator instance will rely upon, including:
The Configuration Extensions information includes extensible configuration features that includes end user provided Optimizer.
The principal API classes are: | | |
- net.jxta.ext.config.AbstractConfigurator
- net.jxta.ext.config.Configurator
| | | addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| |
> > | note: see #1449
addResource(PROFILE_KEY, "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
| | | With an AbstractConfigurator implementation in hand and registered with the JXTA Platform as the configuration delegate we now turn to the principal configuration class, aptly named Configurator.
The Configurator class serves to programatically create new and update existing PlatformConfig instances. As mentioned above, a Configurator can be managed via the AbstractConfigurator class or used standalone. For runtime environements, use of the AbstractConfigurator is encouraged as much of the file systems mechanics et al are managed by the ext:config framework. On the other hand, Configurator can be used to generate PlatformConfig objects for use elsewhere such as cluster configuration. | | | All of the above are invokable but typical use case calls for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile). | |
< < | wip: overview the above
Attributes ... | > > |
Profile (aka ext:config/profile) | | | | |
< < | Security ... | > > | Provides a means to declaratively manage Configurator processes by quantifing varying configuration classes into common domains in the form of "profiles." | | | | |
< < | Services ... | > > | A series of profile presets exist including: | | | | |
< < | Network ... | > > |
| name | description |
| EDGE | primarily a service consumer |
| SUPER | primarily a service provisioner |
| LOCAL | primarily useful for development |
| DEFAULT | equivalent to EDGE |
| | | | |
< < | Endpoint ... | > > | Most of the included profiles include subtle variations. Further, one can construct entirely new profiles that support specific application requirements. | | | | |
< < | Miscellaneous ... | > > | All addresses are of the form URI. Addresses that do not specify scheme information will be defaulted accordingly to the respective context. Partial URI addresses will be templated with the respective context such as the local IP address, etc. | | | | |
< < |
Profile (aka ext:config/profile) | > > | All fields have backing defaults enabling one to specify only the required overrides in order to construct complete configuration profiles. | | | | |
< < | The ext:config/profile tier adds a declarative model to the afore mentioned API. The principal ext:config/profile class is: | > > | The principal ext:config/profile class is: | | |
- net.jxta.ext.config.Profile
| |
< < | The Profile class includes a number of profile definitions, including:
| name | description |
| Profile.EDGE | prototypical client |
| Profile.EDGE_TCP | |
| Profile.EDGE_HTTP | |
| Profile.SUPER | provisions rendezvous and relay services |
| Profile.SUPER_TCP | |
| Profile.SUPER_HTTP | |
| Profile.RENDEZVOUS | provisions rendezvous services |
| Profile.RENDEZVOUS_TCP | |
| Profile.RENDEZVOUS_HTTP | |
| Profile.RELAY | provisions relay service |
| Profile.RELAY_TCP | |
| Profile.RELAY_HTTP | |
| Profile.LOCAL | loopback; optimal for standalone development or demos |
| | | For added flexibility, profiles can also be instantiated with either an URL or InputStream parameter the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd file. This approach eases deployments by centrally managing application configuration meta data which is then accessed at application runtime.
Following is the prototypical edge profile which can serve as the basis for creating your specialized Profile: | | | wip ... | |
< < | | > > | | | | Just Code
Following are the steps necessary to compile and run the included functional code samples. The prerequisites are: |
|
<<O>> Difference Topic
ExtConfig
(4 - 22 Jul 2005 - Main.turbogeek)
|
| |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease. | | | } catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (ResourceNotFoundException? rnfe) { | |
< < | rnfe.printStactTrace(); | > > | rnfe.printStackTrace(); | | | }
| | | Have fun! Learn by doing! | |
> > | Caution editing your profile.xml
You might encounter the following exception. This can be caused by a certificate tag in the peer section. In this case, the problem was that the <rootCert address=""/> that was there, but no cert address was provided. The actual error thrown deep in the java security was that the key was too long("Could not parse certificate"). In fact there was no key, just gibberish. Removal of the tag solves the problem.
<ERROR 2005-07-22 13:29:33,526 JxtaConfig::File;)V:187> Error initializing configuration
java.lang.IllegalArgumentException: Failed to process cert
at net.jxta.impl.protocol.PSEConfigAdv.setCert(Ljava.lang.String;)V(PSEConfigAdv.java:355)
at net.jxta.ext.config.Configurator.setRootCertificateBase64(Ljava.lang.String;)V(Configurator.java:1271)
at net.jxta.ext.config.Configurator.process(Lnet.jxta.ext.config.Profile;Z)V(Configurator.java:2416)
at net.jxta.ext.config.Configurator.process(Lnet.jxta.ext.config.Profile;)V(Configurator.java:2345)
at net.jxta.ext.config.Configurator.<init>(Ljava.net.URI;Lnet.jxta.ext.config.Profile;)V(Configurator.java:431)
at com.cluck.jxta.util.JxtaConfig.<init>(Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.lang.String;Ljava.io.File;)V(JxtaConfig.java:84)
....
| | |
Resources |
|
<<O>> Difference Topic
ExtConfig
(3 - 13 Apr 2005 - Main.gonzo)
|
|
<<O>> Difference Topic
ExtConfig
(2 - 24 Mar 2005 - Main.turbogeek)
|
|
<<O>> Difference Topic
ExtConfig
(1 - 19 Feb 2005 - Main.gonzo)
|
|
> > |
| META TOPICPARENT | name="WebHome" |
ext:config - flexible JXTA configuration with ease.
Table of Contents
Abstract
The ext:config API is an optional JXTA extension that both eases and extends the core JXTA configuration principals. This is achieved through the combination of a comprehensive API implemented with optimal defaults encompassed with optional declarative models and UI constructs.
The principal ext:config constituents are:
Dependencies
At present, the required ext:config jars are the following:
- JXTA
- 3rd party
- jdom.jar
- jaxen.jar
- jaxen-jdom.jar
- saxpath.jar
note: work is underway to replace the afore mentioned 3rd party jars with the JAXP 1.3 equivalent at which time for JRE 1.5 runtimes will require no extra jars and JRE 1.4 runtimes will require only 1 extra jar.
These jars can be obtained the code below and additionally from the download and bootstrap process referenced in the resources section.
API (aka ext:config)
The ext:config API is the core of the ext:config package with both the profile and ext:config/ui tiers layering above, in succession. The principal API clases are:
- net.jxta.ext.config.AbstractConfigurator
- net.jxta.ext.config.Configurator
A number of supporting classes are also available that aid in the configuration management process.
The primary ext:config class a developer will use is AbstractConfigurator. This class implements the JXTA PlatformConfigurator interface and includes one abstract method:
public abstract PlatformConfig createPlatformConfig(PlatformConfigurator configurator)
throws ConfiguratorException;
AbstractConfigurator implementations are notified via the createPlatformConfig(PlatformConfigurator) during JXTA Platform startup process when configuration data is required either as missing or incomplete. It is at this time applications can inject configuration details into the process.
As such, the following is a complete JXTA configurator minus the requisite application specify configuration details:
import net.jxta.ext.config.AbstractConfigurator;
import net.jxta.exception.ConfiguratorException;
import net.jxta.impl.peergroup.PlatformConfigurator;
import net.jxta.impl.protocol.PlatformConfig;
public class MyConfigurator
extends AbstractConfigurator {
public PlatformConfig createPlatformConfig(PlatformConfigurator pc)
throws ConfiguratorException {
// xxx: application specific configuration logic
return pc.getPlatformConfig();
}
}
In order to override the default JXTA Platform configuration process you register your AbstractConfigurator implementation with the Platform as the configuration delegate:
MyConfigurator.register(MyConfigurator.class);
In order to manipulate the configuration process during each and every startup one can override the updatePlatformConfig(PlatformConfigurator) method:
public PlatformConfig updatePlatformConfig(PlatformConfigurator configurator)
throws ConfiguratorException
The corresponding AbstractConfigurator implementation is thusly notified each time just prior to JXTA Platform start up.
A number of resource management APIs exist which serve to transfer named resources into the resulting JXTA working directory. Resources can be of any form and are accessed via unique names which, in turn, are mapped to file names hosted under the afore mentioned directory. This way, a developer can scope application data to distinct application instances.
Following is a resource management example derived from MyJXTA:
addResource("profile.xml", "/net/jxta/myjxta/resources/profile.xml");
addResource("log4j.xml", "/net/jxta/myjxta/resources/log4j.xml");
With an AbstractConfigurator implementation in hand and registered with the JXTA Platform as the configuration delegate we now turn to the principal configuration class, aptly named Configurator.
The Configurator class serves to programatically create new and update existing PlatformConfig instances. As mentioned above, a Configurator can be managed via the AbstractConfigurator class or used standalone. For runtime environements, use of the AbstractConfigurator is encouraged as much of the file systems mechanics et al are managed by the ext:config framework. On the other hand, Configurator can be used to generate PlatformConfig objects for use elsewhere such as cluster configuration.
The lifecycle of a Configurator is typically quite short. Initially, a few key static constructs are invoked in order to establish a baseline Configurator instance. Firstly, a default PlatformConfig object is processed followed by the protected Profile.SEED profile. Lastly, the default JXTA_HOME is set to the .jxta directory hosted in the user's home directory, programmactically as follows:
setHome(new File(new File(System.getProperty("user.home")), ".jxta"));
note: Setting the JXTA_HOME via a static method has proven problematic and as such is currently under review. A likely refactor may include the JXTA_HOME as a constructor argument.
Upon instantiation, the Configurator object looks for a PlatformConfig in the specified JXTA_HOME and if found is processed to establish the relevant instance state. If a PlatformConfig is not found then a Profile by the name profile.xml hosted in the JXTA_HOME directory will be sought out and if found used to specify the relevant instance state. Failing to find
either of the PlatformConfig and profile.xml files in the specified JXTA_HOME the default profile Profile.DEFAULT (which is effectively Profile.EDGE) will be used to establish the instance state.
Lastly, the provided constructor arguments are accessed accordingly. None of the Configurator constructors throw exceptions so creating a new instance is relatively ensured. The principal constructors are as follows:
- Configurator(String name, String password)
- Configurator(Profile)
- Configurator(PlatformConfig)
note: Deprecated constructors are not included. In addition, a JXTA_HOME constructor may be added at a future time in order to address the static concern noted above.
The sole objective of the Configurator is to construct a viable PlatformConfig object. To this end there are two primary PlatformConfig generation methods:
- public PlatformConfig getPlatformConfig() throws ConfiguratorException
- public boolean save() throws ConfiguratorException
- public boolean save(File pc) ConfiguratorException
note: The save() method simply invokes save(new File(getHome(), "PlatformConfig"))
The ConfiguratorException objects are chained such that all causes are retrievable via respective iterators.
At this point we are now armed with the ability to construct a trivial configurator:
import net.jxta.ext.config.Configurator;
import net.jxta.exception.ConfiguratorException;
import java.util.Iterator;
...
Configurator c = new Configurator("usr", "pwd");
try {
c.save();
} catch (ConfiguratorException ce) {
for (Iterator c = ce.getCauses().iterator(); c.hasNext(); ) {
Throwable t = (Throwable)c.next();
System.out.println(t.getMesasge());
t.printStackTrace(System.out);
}
}
There you have it. Effectively JXTA configuration accomplished in what amounts to 4 lines of code. Alas, true life is typically not so simple. as such we next turn to the number of Configurator getter/setter methods that provide for ultimate JXTA configuration tuning. Before doing so, let's dive down into the PlatformConfig processing internals a bit.
The save methods actually invoke the getPlatformConfig() method. As such, the only real function of the save() methods are to persist a PlatformConfig, as XML, to the relevant file system. With that, our attention turns back to the getPlatformConfig() method. In short, the following steps are executed in order resulting in either a valid PlatformConfig object or a causal ConfiguratorException exception:
- normalization
- optimization
- validation
- PlatformConfig construction
Taking each of these in turn we start with normalization. Normalization starts out by filling in any blank entries with the relvant defaults. No exceptions or faults are generated during this process. wip: describe address macro expansion
Next up, the optimizer kicks in by iterating the current and recently normalized Configurator state through all registered Optimizers in succession. wip: detail Optimizer interface, registration
Following the resultant Configurator state is exercised against a series of internal heuristics that check for PlatformConfig viability. This process, alone, can throw a ConfiguratorException.
Upon passing the validity stage all that remains is PlatformConfig creation whereby the Configurator state is transferred into a representative PlatformConfig instance.
At this point we should step back and inventory the principal getter/setter methods that are available prior to PlatformConfig generation. Configurator hosts a significantly large number of prototypical getter/setter methods that can be logically grouped as follows:
- attributes (eg name, description, id, debug)
- security (user, password)
- services
- RendeZvous
- Relay
- Proxy
- network
- TCP
- HTTP
- others as implemented
- endpoint
- miscellaneous
All of the above are invokable but typical use case calls for only focussing on the relevant domains after instantiating the Configurator with the relevant context (see Profile).
wip: overview the above
Attributes ...
Security ...
Services ...
Network ...
Endpoint ...
Miscellaneous ...
Profile (aka ext:config/profile)
The ext:config/profile tier adds a declarative model to the afore mentioned API. The principal ext:config/profile class is:
- net.jxta.ext.config.Profile
The Profile class includes a number of profile definitions, including:
| name | description |
| Profile.EDGE | prototypical client |
| Profile.EDGE_TCP | |
| Profile.EDGE_HTTP | |
| Profile.SUPER | provisions rendezvous and relay services |
| Profile.SUPER_TCP | |
| Profile.SUPER_HTTP | |
| Profile.RENDEZVOUS | provisions rendezvous services |
| Profile.RENDEZVOUS_TCP | |
| Profile.RENDEZVOUS_HTTP | |
| Profile.RELAY | provisions relay service |
| Profile.RELAY_TCP | |
| Profile.RELAY_HTTP | |
| Profile.LOCAL | loopback; optimal for standalone development or demos |
For added flexibility, profiles can also be instantiated with either an URL or InputStream parameter the content of which conforms to the profile schema definition which can be found in both the Profile javadoc and net.jxta.ext.config.resources.profile.xsd file. This approach eases deployments by centrally managing application configuration meta data which is then accessed at application runtime.
Following is the prototypical edge profile which can serve as the basis for creating your specialized Profile:
<!DOCTYPE org.jxta:configuration>
<jxta>
<peer descriptor="edge"/>
<network>
<rendezVous>
<address>//:</address>
</rendezVous>
<relays>
<address>//:</address>
</relays>
</network>
<transport>
<tcp>
<address range="100">
<multicast>udp://224.0.1.85:1234</multicast>
</address>
<publicAddress exclusive="false"/>
</tcp>
<http>
<address range="100"/>
<publicAddress exclusive="false"/>
<proxy enabled="false"/>
</http>
</transport>
<service>
<relay>
<outgoing enabled="true"/>
</relay>
</service>
</jxta>
Assuming the above profile was copied to a file, say /tmp/myprofile.xml, and modified as needed one could instantiate the resulting specialized Profile as follows:
import net.jxta.ext.config.Profile;
import net.jxta.ext.config.ResourceNotFoundException;
import java.net.URL;
import java.net.MalformedURLException;
...
Profile p = null;
try {
p = new Profile(new URL("file:///tmp/myprofile.xml"));
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (ResourceNotFoundException rnfe) {
rnfe.printStactTrace();
}
The edge profile does not include all possible configuration options as some services are not enabled. Further, defaults, when used, are not duplicated thereby simplifying overall profile usage. Following is a comprehensive breakdown of the principal configuration elements:
| peer | peer description | | | | |
| | descriptor | profile description | | | |
| | home | JXTA_HOME | | | |
| | trace | debug level | | | |
| | security | | | | |
| | proxy | | | | |
| network | subscribed services | | | | |
| | rendezVous | subscribed rendezVous services | | | |
| | | bootstrap | seeding URL | | |
| | | discovery | disallow usage of discovered rendezVous | | |
| | | address(es) | service URI | | |
| | relays | subscribed relays services | | | |
| | | bootstrap | seeding URL | | |
| | | discovery | disallow usage of discovered relays | | |
| | | address(es) | service URI | | |
| transport | peer address(es) | | | | |
| | tcp | TCP endpoint | | | |
| | | address | endpoint URI | | |
| | | range | port range | | |
| | | multicast | muticast URI | | |
| | | | enabled | multicast controller | |
| | | publicAddress | public endpoint URI | | |
| | | | enabled | public address controller | |
| | | proxy | proxy address | | |
| | http | HTTP endpoint | | | |
| | | address | endpoint URI | | |
| | | range | port range | | |
| | | publicAddress | public endpoint URI | | |
| | | proxy | proxy address | | |
| service | provisioned services | | | | |
| | rendezVous | provisioned rendezVous service | | | |
| | | enabled | rendezVous controller | | |
| | | autoStart | rendezVous provisioning policy in milliseconds | | |
| | | | enabled | autoStart controller | |
| | relay | provisioned relay service | | | |
| | | enabled | relay controller | | |
| | | queueSize | relay queue size | | |
| | | incoming | | | |
| | | | enabled | incoming controller | |
| | | | maximum | maximum messages | |
| | | | lease | lifetime in milliseconds | |
| | | outgoing | | | |
| | | | enabled | outgoing controller | |
| | | | maximum | maximum messages | |
| | | | lease | lifetime in milliseconds | |
| | endpoint | | | | |
| | | queueSize | message queue size | | |
| | proxy | | | | |
| | | enabled | proxy controller | | |
| configuration | | | | | |
| | optimizer(s) | configuration optimization | | | |
| | | class | optimizer class name | | |
| | | | property(s) | optimizer attributes | |
| | | | | name | value |
Bringing it all together, one can trivially instantiate a Configurator with a selected Profile instance as a constructor argument as follows:
Configurator c = new Configurator(Profile.EDGE);
The resulting Configurator can readily be manipulated by any of the available APIs. As such, profiles are used to declaratively instantiate an application Configurator via a configuration meta-model. The resulting Configurator instance can, in turn, be adjusted via any of the provided APIs. Using Profiles one can readily experiment with varying models without having to recompile a line of code. Lastly, profiles are used internally by the Configurator class during instantiation to set the relevant defaults.
UI (aka ext:config/ui)
Lastly, the ext:config/ui tier provides an extensible UI above the afore mentioned ext:config/profile tier.
wip ...
Just Code
Following are the steps necessary to compile and run the included functional code samples. The prerequisites are:
- J2SE (1.5 recommended0
- Ant
Obtain a working copy of the ext-config-lab.zip code samples and uncompress it accordingly followed by changing your working directory to that of the top-level jxta directory provided by the distribution. Running Ant with no arguments will display the usage message:
% ant
Buildfile: build.xml
usage:
[echo] % ant [option]
[echo] [exercise number]
[echo] all
[echo] clean
The excercises are contained under the src directory and organized as incremental and progressive code samples. The lib directory includes the necessary JXTA and ext:config libraries:
JXTA jars:
- bcprov-jdk14.jar
- javax.servlet.jar
- jxta.jar
- log4j.jar
- org.mortbay.jetty.jar
ext:config jars:
- jaxen-core.jar
- jaxen-jdom.jar
- jdom.jar
- jxtaext.jar
- saxpath.jar
note: the ext:config jars will likely soon be replaced with the JAXP 1.3 equivalents
To run an excercise simply provide the excercise directory as an Ant argument:
% ant 1
Buildfile: build.xml
http.proxy:
socks.proxy:
prepare:
1:
1.compile:
compile:
1.run:
run:
[java] create PlatformConfig with the following properties:
[java] name = MyPeerName
[java] description = MyPeerDescription
[java] principal = MyPeerPrincipal
[java] password = MyPeerPassWord
[java] saving PlatformConfig to: .../jxta/build/1/home
BUILD SUCCESSFUL
Total time: 9 seconds
Feel free to make changes to the exercises via your editor of choice and recompile and run them via Ant. You can always start over if needed by uncompressing the distribution file.
Have fun! Learn by doing!
Resources
- ext:config API - note: package net.jxta.ext.config
- ext-config-lab.zip
- JXTA Downloads
- JXTA Bootstrap
- JXTA jar dependencies
-- JamesTodd - 01 Feb 2005 |
|