Author: midon
Date: Wed Jun 11 10:11:13 2008
New Revision: 666734
URL: http://svn.apache.org/viewvc?rev=666734&view=rev
Log:
Merge branch 'epr-config_doc'
Modified:
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/EndpointReferenceContext.java
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
ode/trunk/utils/src/main/java/org/apache/ode/utils/HierarchicalProperties.java
ode/trunk/utils/src/test/java/org/apache/ode/utils/HierarchicalPropertiesTest.java
Modified:
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/EndpointReferenceContext.java
URL:
http://svn.apache.org/viewvc/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/EndpointReferenceContext.java?rev=666734&r1=666733&r2=666734&view=diff
==============================================================================
---
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/EndpointReferenceContext.java
(original)
+++
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/EndpointReferenceContext.java
Wed Jun 11 10:11:13 2008
@@ -56,9 +56,11 @@
EndpointReference convertEndpoint(QName targetType, Element
sourceEndpoint);
/**
- *
+ * Convert an endpoint reference into a set of key/value pairs that may be
necessary to look up config information.
+ * This implies a contract between the implementation and the caller.
+ * <p/>For instance a WSDL endpoint reference may be converted into
{service => foo, port => bar}.
* @param epr
- * @return
+ * @return a map containing the relevant information for config lookup
*/
Map getConfigLookup(EndpointReference epr);
}
Modified:
ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
URL:
http://svn.apache.org/viewvc/ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java?rev=666734&r1=666733&r2=666734&view=diff
==============================================================================
--- ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
(original)
+++ ode/trunk/bpel-api/src/main/java/org/apache/ode/bpel/iapi/ProcessConf.java
Wed Jun 11 10:11:13 2008
@@ -143,6 +143,11 @@
boolean isEventEnabled(List<String> scopeNames, BpelEvent.TYPE type);
+ /**
+ * Returns a list of properties associtated to this endpoint.
+ * @param epr
+ * @return map of property/value pairs
+ */
public Map<String, String> getEndpointProperties(EndpointReference epr);
}
Modified:
ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
URL:
http://svn.apache.org/viewvc/ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java?rev=666734&r1=666733&r2=666734&view=diff
==============================================================================
---
ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
(original)
+++
ode/trunk/bpel-store/src/main/java/org/apache/ode/store/ProcessConfImpl.java
Wed Jun 11 10:11:13 2008
@@ -90,11 +90,11 @@
// cache the inMemory flag because XMLBeans objects are heavily
synchronized (guarded by a coarse-grained lock)
private volatile boolean _inMemory = false;
- // provide the IL properties
- private HierarchicalProperties ilProperties;
- // monitor the IL property file and reload it if necessary
- private ILWatchDog ilWatchDog;
- private final ReadWriteLock ilPropertiesLock = new
ReentrantReadWriteLock();
+ // provide the EPR properties
+ private HierarchicalProperties eprProperties;
+ // monitor the EPR property file and reload it if necessary
+ private EPRPropertiesWatchDog eprPropertiesWatchDog;
+ private final ReadWriteLock eprPropertiesLock = new
ReentrantReadWriteLock();
private EndpointReferenceContext eprContext;
@@ -110,7 +110,7 @@
_type = type;
_inMemory = _pinfo.isSetInMemory() && _pinfo.getInMemory();
this.eprContext = eprContext;
- ilWatchDog = new ILWatchDog();
+ eprPropertiesWatchDog = new EPRPropertiesWatchDog();
initLinks();
initMexInterceptors();
@@ -373,61 +373,61 @@
// update properties if necessary
// do it manually to save resources (instead of using a thread)
- ilWatchDog.check();
- if (ilProperties == null) {
+ eprPropertiesWatchDog.check();
+ if (eprProperties == null) {
return Collections.EMPTY_MAP;
} else {
// take a lock so we can have a consistent snapshot of the
properties
- ilPropertiesLock.readLock().lock();
+ eprPropertiesLock.readLock().lock();
try {
- return ilProperties.getProperties(service, port);
+ return eprProperties.getProperties(service, port);
} finally {
- ilPropertiesLock.readLock().unlock();
+ eprPropertiesLock.readLock().unlock();
}
}
}
/**
* Manage the reloading of the propery file every [EMAIL PROTECTED]
org.apache.ode.utils.fs.FileWatchDog#DEFAULT_DELAY}.
- * The check is done manually, meaning that [EMAIL PROTECTED] #check()}
must be invoked each time _ilProperties is accessed.
+ * The check is done manually, meaning that [EMAIL PROTECTED] #check()}
must be invoked each time eprProperties is accessed.
*/
- private class ILWatchDog extends FileWatchDog {
- public ILWatchDog() {
+ private class EPRPropertiesWatchDog extends FileWatchDog {
+ public EPRPropertiesWatchDog() {
super(_du.getEPRConfigFile());
}
protected void init() {
- ilPropertiesLock.writeLock().lock();
+ eprPropertiesLock.writeLock().lock();
try {
- if (ilProperties == null) {
+ if (eprProperties == null) {
try {
- ilProperties = new HierarchicalProperties(super.file);
+ eprProperties = new HierarchicalProperties(super.file);
} catch (IOException e) {
- throw new ContextException("Integration-Layer
Properties cannot be loaded!", e);
+ throw new ContextException("EPR Config Properties
cannot be loaded!", e);
}
} else {
- ilProperties.clear();
+ eprProperties.clear();
}
} finally {
- ilPropertiesLock.writeLock().unlock();
+ eprPropertiesLock.writeLock().unlock();
}
}
protected boolean isInitialized() {
- return ilProperties != null;
+ return eprProperties != null;
}
protected void doOnUpdate() {
- ilPropertiesLock.writeLock().lock();
+ eprPropertiesLock.writeLock().lock();
try {
init();
try {
- ilProperties.loadFile();
+ eprProperties.loadFile();
} catch (IOException e) {
- throw new ContextException("Integration-Layer Properties
cannot be loaded!", e);
+ throw new ContextException("EPR Config Properties cannot
be loaded!", e);
}
} finally {
- ilPropertiesLock.writeLock().unlock();
+ eprPropertiesLock.writeLock().unlock();
}
}
}
Modified:
ode/trunk/utils/src/main/java/org/apache/ode/utils/HierarchicalProperties.java
URL:
http://svn.apache.org/viewvc/ode/trunk/utils/src/main/java/org/apache/ode/utils/HierarchicalProperties.java?rev=666734&r1=666733&r2=666734&view=diff
==============================================================================
---
ode/trunk/utils/src/main/java/org/apache/ode/utils/HierarchicalProperties.java
(original)
+++
ode/trunk/utils/src/main/java/org/apache/ode/utils/HierarchicalProperties.java
Wed Jun 11 10:11:13 2008
@@ -36,41 +36,54 @@
import java.util.Iterator;
/**
- * This class load a regular property file in [EMAIL PROTECTED]
java.util.Properties} instance. The main feature is that property can
- * be chained in three levels. Then when querying for a property, if it's not
found in the deepest level,
- * the parent will be queryed and so on.
+ * <h3>3-level Property File</h3>
+ * This class loads a regular property file. The main feature is that property
can
+ * be chained in three levels. Which are, from highest to deepest:
+ * <ol>
+ * <li>[EMAIL PROTECTED] property}: defines the default value for the given
property</li>
+ * <li>[EMAIL PROTECTED] service-ns.service-localname.ode.property}: defines
the value for all ports of the given service</li>
+ * <li>[EMAIL PROTECTED] service-ns.service-localname.port.ode.property}:
defines the value for the given port</li>
+ * </ol>
+ * Then, properties might be queried with a service and/or port. The
corresponding level will be queried for the associated value,
+ * if not found the level n-1 is queried, and so on until the default value.
* <p/>
- * A prefix must be defined to discriminate the property name and the level-1,
level-2 names. The default prefix is [EMAIL PROTECTED] #ODE_PREFFIX}.
+ * Properties must respect the following pattern: [EMAIL PROTECTED]
[service-ns.service-localname.[port.]prefix.]property}
* <p/>
- * Properties must respect the following pattern:
[level1.[level2.]prefix.]property
+ * Values may contain some environment variables. For instance, [EMAIL
PROTECTED] message=You're using ${java.version}}.
* <p/>
- * A concrete use case could be the definition of properties for wsdl services
and ports.
- * <br/>Level 0 would be: values common to all services and ports.
- * <br/>Level 1: values common to a given service.
- * <br/>Level 2: values common to a given port.
+ * <h3>Namespaces Alias</h3>
+ * To save some typing and make sure the property is valid, namespaces might
be aliased.<br/>
+ * To do so, add a property similar to: [EMAIL PROTECTED]
alias.my-ns-nickname=http://mynamespace.org}.
+ * <br/>Then instead of typing [EMAIL PROTECTED]
http://mynamespace.org.mylocalname.myproperty=my_value} (which is not a valid a
property btw}, write: [EMAIL PROTECTED]
my-ns-nickname.mylocalname.myproperty=my_value}
+ *
* <p/>
+ * <h3>Examples</h3>
* For instance, if the property file looks like this:
* <pre>
- * timeout=40000
- * film-service.port-of-cannes.ode.timeout=50000
- * <p/>
+ * alias.ex_ns=http://examples.org
+ *
* max-redirects=30
- * brel-service.ode.max-redirects=40
- * brel-service.port-of-amsterdam.ode.max-redirects=60
+ * timeout=40000
+ *
+ * ex_ns.film-service.port-of-cannes.ode.timeout=50000
+ *
+ * ex_ns.brel-service.ode.max-redirects=40
+ * ex_ns.brel-service.port-of-amsterdam.ode.max-redirects=60
* </pre>
* The following values may be expected:
* <pre>
- * getProperty("max-redirects") => 30
- * getProperty("brel-service", "max-redirects") => 40
- * getProperty("brel-service", "port-of-amsterdam", "max-redirects") => 60
- * <p/>
- * getProperty("film-service", "timeout") => 40000
- * getProperty("film-service", "port-of-cannes", "timeout") => 50000
- * getProperty("brel-service", "port-of-amsterdam", "timeout") => 40000
+ * getProperty("max-redirects")
=> 30
+ * getProperty("http://examples.org", "brel-service", "max-redirects")
=> 40
+ * getProperty("http://examples.org", "brel-service", "port-of-amsterdam",
"max-redirects") => 60
+ *
+ * getProperty("http://examples.org", "film-service", "timeout")
=> 40000
+ * getProperty("http://examples.org", "film-service", "port-of-cannes",
"timeout") => 50000
+ * getProperty("http://examples.org", "brel-service", "port-of-amsterdam",
"timeout") => 40000
+ *
+ * getProperties("http://examples.org", "film-service") =>
Map{"timeout"=>"40000", "max-redirect"=>"30"}
+ * getProperties("http://examples.org", "film-service", "port-of-cannes") =>
Map{"timeout"=>"50000", "max-redirect"=>"30"}
* </pre>
* <p/>
- * Values may contain some environment variables. For instance, message=You're
using ${java.version}.
- * <p/>
* This class is not thread-safe.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Alexis Midon</a>
@@ -83,6 +96,7 @@
// the raw properties as of loaded from the filesystem
private Properties props = new Properties();
+ // map <URI, alias>
private Map<String, String> aliases = new HashMap<String, String>();
private File file;
private String prefix;
@@ -105,10 +119,9 @@
private transient MultiKeyMap cacheOfImmutableMaps = new MultiKeyMap();
/**
- * @param file the property file to be loaded. The file may not exist.
- * But if the file exists it has to be a file (not a
directory), otherwhise an IOException is thrown.
+ * @param file the property file to be loaded. If the file does not
exist, NO exception is thrown. Property map will be empty
* @param prefix the property prefix
- * @throws IOException
+ * @throws IOException if the file exists but is a directory
*/
public HierarchicalProperties(File file, String prefix) throws IOException
{
this.file = file;
@@ -117,22 +130,28 @@
loadFile();
}
+ /**
+ * Use [EMAIL PROTECTED] #ODE_PREFFIX} as the prefix
+ [EMAIL PROTECTED] #HierarchicalProperties(java.io.File, String)
+ */
public HierarchicalProperties(File file) throws IOException {
this(file, ODE_PREFFIX);
}
/**
- * Clear all existing content, read the file and parse each property.
Simply logs a message and returns if the file does not exist.
- *
+ * Clear all existing content, re-read the file and parse each property.
If the file does not exist, content is cleared and method returns (no exception
will be thrown).
+ * <br/>Keep in mind that this class is not thread-safe. It's the caller's
responsability to make sure that one thread is not querying some properties
+ * while another is re-loading the file, for instance.
* @throws IOException if the file is a Directory
*/
public void loadFile() throws IOException {
+ // #1. clear all existing content
+ clear();
+
if (!file.exists()) {
if (log.isDebugEnabled()) log.debug("File does not exist [" + file
+ "] Properties will be empty.");
return;
}
- // #1. clear all existing content
- clear();
// #2. read the file
FileInputStream fis = new FileInputStream(file);
@@ -196,7 +215,7 @@
}
/**
- * Clear all content. If [EMAIL PROTECTED] #loadFile()} is not invoked
later, all returned values will be null.
+ * Clear all content.
*/
public void clear() {
props.clear();
@@ -214,6 +233,9 @@
return (ChainedMap) o;
}
+ /**
+ * @see #getProperties(javax.xml.namespace.QName)
+ */
public Map getProperties(String serviceNamespaceURI, String
serviceLocalPart) {
return getProperties(new QName(serviceNamespaceURI, serviceLocalPart));
}
@@ -221,38 +243,40 @@
/**
* @param service
* @return a map containing all the properties for the given service.
- * @see #getProperties(String, String)
+ * @see #getProperties(javax.xml.namespace.QName, String)
*/
public Map getProperties(QName service) {
return getProperties(service, null);
}
+ /**
+ * @see #getProperties(javax.xml.namespace.QName, String)
+ */
public Map getProperties(String serviceNamespaceURI, String
serviceLocalPart, String port) {
return getProperties(new QName(serviceNamespaceURI, serviceLocalPart),
port);
}
/**
- * Return a map containing all the properties for the given port. The map
is an immutable snapshot of the properties.
- * Meaning that futur changes to the properties will NOT be reflected in
the returned map.
- *
+ * Return a map containing all the properties for the given service/port.
The map is an immutable snapshot of the properties.
+ * <br/>These immutable maps are cached to avoid too many map instances.
+ * <br/>If [EMAIL PROTECTED] port} is null then properties defined at the
service level are returned.
* @param service
* @param port
- * @return a map containing all the properties for the given port
+ * @return an immutable map containing all the properties for the given
port
*/
public Map getProperties(QName service, String port) {
// no need to go further if no properties
if (hierarchicalMap.isEmpty()) return Collections.EMPTY_MAP;
- service = resolveAlias(service);
- // else check the cache of ChainedMap already converted into immutable
maps
+ service = resolveNamespace(service);
+ // check if the cache of immutable maps contains this key
Map cachedMap = (Map) this.cacheOfImmutableMaps.get(service, port);
if (cachedMap != null) {
return cachedMap;
}
- // else get the corresponding ChainedMap and convert it into a Map
+ // if not, get the corresponding ChainedMap and convert it into a Map
ChainedMap cm = (ChainedMap) hierarchicalMap.get(service, port);
- // if this port is not explicitly mentioned in the multimap, get the
default values.
if (cm == null) {
cm = (ChainedMap) hierarchicalMap.get(service, null);
if (cm == null) {
@@ -260,52 +284,75 @@
return getProperties((QName) null, null);
}
}
+
+ // convert the ChainedMap into a Map and cache it
Map snapshotMap = new HashMap(cm.size() * 15 / 10);
for (Object key : cm.keySet()) {
snapshotMap.put(key, cm.get(key));
}
snapshotMap = Collections.unmodifiableMap(snapshotMap);
- // put it in cache to avoid creating one map at each invocation
+ // put it in cache to avoid creating one map on each invocation
this.cacheOfImmutableMaps.put(service, port, snapshotMap);
return snapshotMap;
}
+ /**
+ *
+ * @param property the property to be queried
+ * @return the default value for this property
+ */
public String getProperty(String property) {
return (String) getRootMap().get(property);
}
+ /**
+ * @see #getProperty(javax.xml.namespace.QName, String)
+ */
public String getProperty(String serviceNamespaceURI, String
serviceLocalPart, String property) {
return getProperty(new QName(serviceNamespaceURI, serviceLocalPart),
property);
}
+ /**
+ * @return the value associated to this property for the given service
+ */
public String getProperty(QName service, String property) {
return getProperty(service, null, property);
}
+ /**
+ * @see #getProperty(javax.xml.namespace.QName, String, String)
+ */
public String getProperty(String serviceNamespaceURI, String
serviceLocalPart, String port, String property) {
return getProperty(new QName(serviceNamespaceURI, serviceLocalPart),
port, property);
}
+ /**
+ * Equivalent [EMAIL PROTECTED] getProperties(service,port).get(property)}
+ * @return the value associated to this property for the given service/port
+ */
public String getProperty(QName service, String port, String property) {
- ChainedMap cm = (ChainedMap)
hierarchicalMap.get(resolveAlias(service), port);
- // if this port is not explicitly mentioned in the multimap, get the
default values.
- if (cm == null) cm = getRootMap();
- return (String) cm.get(property);
- }
-
- public String getPrefix() {
- return prefix;
+ return (String) getProperties(service,port).get(property);
}
- private QName resolveAlias(QName service) {
- if (service != null && aliases.containsKey(service.getNamespaceURI()))
{
- return new QName(aliases.get(service.getNamespaceURI()),
service.getLocalPart());
+ /**
+ * Resolved the service qname associated to the given aliased service name.
+ * <p/>For instance, [EMAIL PROTECTED] resolveAlias(new QName("my-ns",
"a-name"))} will return
+ * [EMAIL PROTECTED] new QName("http://examples.com", "a-name")} if the
alias [EMAIL PROTECTED] my-ns => http://examples.com} exists.
+ * @param aliasedServiceName a service name using an alias
+ * @return the qname of the service associated to this alias if defined in
the alias map, or aliasedServiceName itself.
+ */
+ private QName resolveNamespace(QName aliasedServiceName) {
+ if (aliasedServiceName != null &&
aliases.containsKey(aliasedServiceName.getNamespaceURI())) {
+ return new
QName(aliases.get(aliasedServiceName.getNamespaceURI()),
aliasedServiceName.getLocalPart());
}
- return service;
+ return aliasedServiceName;
}
-
+
+ /**
+ * @return an array of strings containing: namespace alias, service, port,
targeted property
+ */
private String[] parseProperty(String property) {
- // aliaas ns, service, port, targeted property
+ // namespace alias, service, port, targeted property
String[] res = new String[4];
int index = property.indexOf(dotted_prefix);
Modified:
ode/trunk/utils/src/test/java/org/apache/ode/utils/HierarchicalPropertiesTest.java
URL:
http://svn.apache.org/viewvc/ode/trunk/utils/src/test/java/org/apache/ode/utils/HierarchicalPropertiesTest.java?rev=666734&r1=666733&r2=666734&view=diff
==============================================================================
---
ode/trunk/utils/src/test/java/org/apache/ode/utils/HierarchicalPropertiesTest.java
(original)
+++
ode/trunk/utils/src/test/java/org/apache/ode/utils/HierarchicalPropertiesTest.java
Wed Jun 11 10:11:13 2008
@@ -46,7 +46,6 @@
assertEquals(msg, hp.getProperty("bar", "brel-service",
"port-of-amsterdam", "timeout"), "40000");
assertEquals(msg, hp.getProperty("foo", "film-service", "timeout"),
"40000");
assertEquals(msg, hp.getProperty("foo", "film-service",
"port-of-cannes", "timeout"), "50000");
- assertEquals(msg,
hp.getProperty("ode.a.property.beginning.with.the.prefix.but.no.service"), "so
green or red?");
}
public void testGetPropertyUsingURI() {
@@ -57,7 +56,10 @@
assertEquals(msg, hp.getProperty("http://bar.com", "brel-service",
"port-of-amsterdam", "timeout"), "40000");
assertEquals(msg, hp.getProperty("http://foo.com", "film-service",
"timeout"), "40000");
assertEquals(msg, hp.getProperty("http://foo.com", "film-service",
"port-of-cannes", "timeout"), "50000");
- assertEquals(msg,
hp.getProperty("ode.a.property.beginning.with.the.prefix.but.no.service"), "so
green or red?");
+
+
+ assertEquals("Default value expected!", hp.getProperty("http://xyz",
"unknown-service", "unknown-port", "timeout"), "40000");
+ assertNull("Should return null when the property has no value",
hp.getProperty("http://xyz", "unknown-service", "unknown-port",
"unknown-property"));
}
public void testGetProperties() {
@@ -71,9 +73,9 @@
public void testCachedGetProperties() {
- assertSame("Snapshot maps should be cached!", hp.getProperties("foo",
"film-service"), hp.getProperties("foo", "film-service"));
- assertSame("Snapshot maps should be cached!", hp.getProperties("foo",
"film-service", "port-of-cannes"), hp.getProperties("foo", "film-service",
"port-of-cannes"));
- assertSame("Snapshot maps should be cached!", hp.getProperties("bla",
"unknown-service"), hp.getProperties("bla", "unknown-service"));
+ assertSame("Snapshot maps should be cached! References must be the
same.", hp.getProperties("foo", "film-service"), hp.getProperties("foo",
"film-service"));
+ assertSame("Snapshot maps should be cached! References must be the
same.", hp.getProperties("foo", "film-service", "port-of-cannes"),
hp.getProperties("foo", "film-service", "port-of-cannes"));
+ assertSame("Snapshot maps should be cached! References must be the
same.", hp.getProperties("bla", "unknown-service"), hp.getProperties("bla",
"unknown-service"));
}
public void testWithNoFile() throws IOException {