[infinispan-commits] Infinispan SVN: r157 - in trunk/core/src: main/java/org/infinispan/config and 5 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Apr 21 09:37:17 EDT 2009


Author: manik.surtani at jboss.com
Date: 2009-04-21 09:37:17 -0400 (Tue, 21 Apr 2009)
New Revision: 157

Added:
   trunk/core/src/test/java/org/infinispan/config/ConfigurationValidityTest.java
Modified:
   trunk/core/src/main/java/org/infinispan/Cache.java
   trunk/core/src/main/java/org/infinispan/config/Configuration.java
   trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java
   trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
   trunk/core/src/main/resources/schema/infinispan-config-4.0.xsd
   trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java
Log:
Test for invalid configurations

Modified: trunk/core/src/main/java/org/infinispan/Cache.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/Cache.java	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/main/java/org/infinispan/Cache.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -48,20 +48,6 @@
  * <p/>
  * Please see the <a href="http://www.jboss.org/infinispan/docs">Infinispan documentation</a> for more details.
  * <p/>
- * A note about return values.  Certain methods on {@link Map} could have indeterminate return values, <i>if</i> the
- * DISTRIBITION cache mode is used in an asynchronous manner <i>and</i> the invocation takes place on a cache instance
- * where the entry involved is not local.  These methods are: <ul> <li>{@link #put(Object, Object)} and its variations,
- * including {@link #putIfAbsent(Object, Object)}</li> <li>{@link #remove(Object)} and its variations</li> <li>{@link
- * #replace(Object, Object)} and its variations</li> </ul> The methods still <i>behave</i> as expected, i.e., {@link
- * #putIfAbsent(Object, Object)} will be a no-op if there is a value present, just that since remote calls are
- * asynchronous and the operation needs to be executed on a remote cache, the calling cache will not wait for a return
- * value.
- * <p/>
- * As such, as a general rule of thumb, return values to these methods should <i>not</i> be used if using DISTRIBUTION
- * in asynchronous mode.
- * <p/>
- * For all other cache modes (including <i>synchronous</i> DISTRIBUTION) these return values are reliable and can be
- * used.
  *
  * @author Mircea.Markus at jboss.com
  * @author Manik Surtani

Modified: trunk/core/src/main/java/org/infinispan/config/Configuration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/Configuration.java	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/main/java/org/infinispan/config/Configuration.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -21,13 +21,13 @@
  */
 package org.infinispan.config;
 
+import org.infinispan.distribution.DefaultConsistentHash;
 import org.infinispan.eviction.EvictionStrategy;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.factories.annotations.NonVolatile;
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.lock.IsolationLevel;
 import org.infinispan.util.ReflectionUtil;
-import org.infinispan.distribution.DefaultConsistentHash;
 
 import java.util.Collections;
 import java.util.List;
@@ -45,9 +45,7 @@
 
    // reference to a global configuration
    private GlobalConfiguration globalConfiguration;
-   private boolean useLockStriping = true;
 
-
    public GlobalConfiguration getGlobalConfiguration() {
       return globalConfiguration;
    }
@@ -74,6 +72,14 @@
       return useLockStriping;
    }
 
+   public boolean isUnsafeUnreliableReturnValues() {
+      return unsafeUnreliableReturnValues;
+   }
+
+   public void setUnsafeUnreliableReturnValues(boolean unsafeUnreliableReturnValues) {
+      this.unsafeUnreliableReturnValues = unsafeUnreliableReturnValues;
+   }
+
    /**
     * Cache replication mode.
     */
@@ -168,7 +174,7 @@
    private long replQueueInterval = 5000;
    private boolean exposeJmxStatistics = false;
    @Dynamic
-   private boolean fetchInMemoryState = true;
+   private boolean fetchInMemoryState = false;
    @Dynamic
    private long lockAcquisitionTimeout = 10000;
    @Dynamic
@@ -200,6 +206,8 @@
    private String consistentHashClass = DefaultConsistentHash.class.getName();
    private int numOwners = 2;
    private long rehashWaitTime = 60000;
+   private boolean useLockStriping = true;
+   private boolean unsafeUnreliableReturnValues = false;
 
    @Start(priority = 1)
    private void correctIsolationLevels() {
@@ -258,8 +266,9 @@
    }
 
    /**
-    * Enables invocation batching if set to <tt>true</tt>.  You still need to use {@link org.infinispan.Cache#startBatch()}
-    * and {@link org.infinispan.Cache#endBatch(boolean)} to demarcate the start and end of batches.
+    * Enables invocation batching if set to <tt>true</tt>.  You still need to use {@link
+    * org.infinispan.Cache#startBatch()} and {@link org.infinispan.Cache#endBatch(boolean)} to demarcate the start and
+    * end of batches.
     *
     * @param enabled if true, batching is enabled.
     * @since 4.0
@@ -660,8 +669,8 @@
    }
 
    /**
-    * Returns the {@link org.infinispan.config.CustomInterceptorConfig}, if any, associated with this configuration object.
-    * The custom interceptors will be added to the cache at startup in the sequence defined by this list.
+    * Returns the {@link org.infinispan.config.CustomInterceptorConfig}, if any, associated with this configuration
+    * object. The custom interceptors will be added to the cache at startup in the sequence defined by this list.
     *
     * @return List of cutom interceptors, never null
     */
@@ -684,4 +693,13 @@
          ReflectionUtil.setValue(this, overriddenField, ReflectionUtil.getValue(overrides, overriddenField));
       }
    }
+
+   public void assertValid() throws ConfigurationException {
+      // certain combinations are illegal, such as state transfer + DIST
+      if (cacheMode.isDistributed() && fetchInMemoryState)
+         throw new ConfigurationException("Cache cannot use DISTRIBUTION mode and have fetchInMemoryState set to true");
+
+      if (cacheMode == CacheMode.DIST_ASYNC && !unsafeUnreliableReturnValues)
+         throw new ConfigurationException("DISTRIBUTION mode cannot be asynchronous without breaking return values in the public API.  To force this, please use the <unsafe /> element, setting the 'unreliableReturnValues' attribute to 'true'.");
+   }
 }

Modified: trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/main/java/org/infinispan/config/parsing/XmlConfigurationParserImpl.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -159,7 +159,7 @@
       configureEviction(getSingleElementInCoreNS("eviction", e), c);
       configureCacheLoaders(getSingleElementInCoreNS("loaders", e), c);
       configureCustomInterceptors(getSingleElementInCoreNS("customInterceptors", e), c);
-
+      configureUnsafe(getSingleElementInCoreNS("unsafe", e), c);
       return c;
    }
 
@@ -212,27 +212,19 @@
          if (existsAttribute(tmp)) config.setNumOwners(getInt(tmp));
          tmp = getAttributeValue(hash, "rehashWait");
          if (existsAttribute(tmp)) config.setRehashWaitTime(getLong(tmp));
-
-         config.setFetchInMemoryState(false);
-
-         // sanity check against the presence of a stateRetrieval element
-         Element ste = null;
-         if ((ste = getSingleElementInCoreNS("stateRetrieval", e)) != null) {
-            tmp = getAttributeValue(ste, "fetchInMemoryState");
-            if (!existsAttribute(tmp) || getBoolean(tmp))
-               throw new ConfigurationException("stateRetrieval cannot be used with cache mode 'DISTRIBUTION'!");
-         }
-      } else {
-         configureStateRetrieval(getSingleElementInCoreNS("stateRetrieval", e), config);
-         if (getSingleElementInCoreNS("l1", e) != null || getSingleElementInCoreNS("hash", e) != null)
-            throw new ConfigurationException("l1 and hash elements cannot be used with cache modes 'REPLICATION' and 'INVALIDATION'!");
+      } else if (getSingleElementInCoreNS("l1", e) != null || getSingleElementInCoreNS("hash", e) != null) {
+         throw new ConfigurationException("l1 and hash elements cannot be used with cache modes 'REPLICATION' and 'INVALIDATION'!");
       }
+      configureStateRetrieval(getSingleElementInCoreNS("stateRetrieval", e), config);
    }
 
    void configureStateRetrieval(Element element, Configuration config) {
       if (element == null) return; //we might not have this configured
       String fetchInMemoryState = getAttributeValue(element, "fetchInMemoryState");
-      if (existsAttribute(fetchInMemoryState)) config.setFetchInMemoryState(getBoolean(fetchInMemoryState));
+      if (existsAttribute(fetchInMemoryState))
+         config.setFetchInMemoryState(getBoolean(fetchInMemoryState));
+      else
+         config.setFetchInMemoryState(true); // set this to true since the element was provided   
       String stateRetrievalTimeout = getAttributeValue(element, "timeout");
       if (existsAttribute(stateRetrievalTimeout)) config.setStateRetrievalTimeout(getLong(stateRetrievalTimeout));
 
@@ -319,6 +311,13 @@
       }
    }
 
+   void configureUnsafe(Element element, Configuration configuration) {
+      if (element != null) {
+         String tmp = getAttributeValue(element, "unreliableReturnValues");
+         if (existsAttribute(tmp)) configuration.setUnsafeUnreliableReturnValues(getBoolean(tmp));
+      }
+   }
+
    void configureInvalidation(Element element, Configuration config) {
       if (element == null) return; //might be replication
       Element async = getSingleElement("async");

Modified: trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/main/java/org/infinispan/manager/DefaultCacheManager.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -334,6 +334,7 @@
          if (overrides != null) c.applyOverrides(overrides);
       }
 
+      c.assertValid();
       Cache cache = new DefaultCacheFactory().createCache(c, globalComponentRegistry, cacheName);
       Cache other = caches.putIfAbsent(cacheName, cache);
       if (other == null) {
@@ -382,7 +383,7 @@
       return globalComponentRegistry.getStatus();
    }
 
-   @ManagedAttribute (description = "the defined cache names and their status")
+   @ManagedAttribute(description = "the defined cache names and their status")
    public String getDefinedCacheNames() {
       StringBuilder result = new StringBuilder("[");
       for (String cacheName : this.configurationOverrides.keySet()) {
@@ -393,12 +394,12 @@
       return result.toString();
    }
 
-   @ManagedAttribute (description = "the total number of defined caches")
+   @ManagedAttribute(description = "the total number of defined caches")
    public String getDefinedCacheCount() {
       return String.valueOf(this.configurationOverrides.keySet().size());
    }
 
-   @ManagedAttribute (description = "number of running caches")
+   @ManagedAttribute(description = "number of running caches")
    public String getCreatedCacheCount() {
       return String.valueOf(this.caches.keySet().size());
    }

Modified: trunk/core/src/main/resources/schema/infinispan-config-4.0.xsd
===================================================================
--- trunk/core/src/main/resources/schema/infinispan-config-4.0.xsd	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/main/resources/schema/infinispan-config-4.0.xsd	2009-04-21 13:37:17 UTC (rev 157)
@@ -55,13 +55,14 @@
          <xs:element name="locking" type="tns:lockingType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="transaction" type="tns:transactionType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="jmxStatistics" type="tns:jmxStatisticsType" minOccurs="0" maxOccurs="1"/>
-         <xs:element name="lazyDeserialization" type="tns:lazyDeserialization" minOccurs="0" maxOccurs="1"/>
+         <xs:element name="lazyDeserialization" type="tns:lazyDeserializationType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="invocationBatching" type="tns:invocationBatchingType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="eviction" type="tns:evictionType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="expiration" type="tns:expirationType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="loaders" type="tns:loadersType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="customInterceptors" type="tns:customInterceptorsType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="clustering" type="tns:clusteringType" minOccurs="0" maxOccurs="1"/>
+         <xs:element name="unsafe" type="tns:unsafeType" minOccurs="0" maxOccurs="1"/>
       </xs:all>
       <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>
@@ -71,8 +72,8 @@
          <xs:element name="sync" type="tns:syncType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="async" type="tns:asyncType" minOccurs="0" maxOccurs="1"/>
          <xs:element name="stateRetrieval" type="tns:stateRetrievalType" minOccurs="0" maxOccurs="1"/>
-         <xs:element name="hash" type="tns:hashType" minOccurs="0" maxOccurs="1" />
-         <xs:element name="l1" type="tns:l1Type" minOccurs="0" maxOccurs="1" />
+         <xs:element name="hash" type="tns:hashType" minOccurs="0" maxOccurs="1"/>
+         <xs:element name="l1" type="tns:l1Type" minOccurs="0" maxOccurs="1"/>
       </xs:all>
       <xs:attribute name="mode">
          <xs:simpleType>
@@ -146,13 +147,17 @@
    </xs:simpleType>
 
    <xs:complexType name="jmxStatisticsType">
-      <xs:attribute name="enabled" type="tns:booleanType"/>      
+      <xs:attribute name="enabled" type="tns:booleanType"/>
    </xs:complexType>
 
-   <xs:complexType name="lazyDeserialization">
+   <xs:complexType name="lazyDeserializationType">
       <xs:attribute name="enabled" type="tns:booleanType"/>
    </xs:complexType>
 
+   <xs:complexType name="unsafeType">
+      <xs:attribute name="unreliableReturnValues" type="tns:booleanType"/>
+   </xs:complexType>
+
    <xs:complexType name="invocationBatchingType">
       <xs:attribute name="enabled" type="tns:booleanType"/>
    </xs:complexType>
@@ -262,6 +267,6 @@
    <xs:complexType name="propertyType">
       <xs:attribute name="name" type="xs:string"/>
       <xs:attribute name="value" type="xs:string"/>
-   </xs:complexType>   
+   </xs:complexType>
 </xs:schema>
 

Added: trunk/core/src/test/java/org/infinispan/config/ConfigurationValidityTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/ConfigurationValidityTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/config/ConfigurationValidityTest.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -0,0 +1,28 @@
+package org.infinispan.config;
+
+import org.testng.annotations.Test;
+
+ at Test(groups = "unit", testName = "config.ConfigurationValidityTest")
+public class ConfigurationValidityTest {
+   public void testInvalidConfigs() {
+      Configuration c = new Configuration();
+      c.setCacheMode(Configuration.CacheMode.DIST_SYNC);
+      c.assertValid();
+      c.setCacheMode(Configuration.CacheMode.DIST_ASYNC);
+      try {
+         c.assertValid();
+         assert false : "Should fail";
+      } catch (ConfigurationException expected) {
+      }
+      c.setUnsafeUnreliableReturnValues(true);
+      c.assertValid();
+      c.setCacheMode(Configuration.CacheMode.DIST_SYNC);
+      c.assertValid();
+      c.setFetchInMemoryState(true);
+      try {
+         c.assertValid();
+         assert false : "Should fail";
+      } catch (ConfigurationException expected) {
+      }
+   }
+}


Property changes on: trunk/core/src/test/java/org/infinispan/config/ConfigurationValidityTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java	2009-04-21 01:04:34 UTC (rev 156)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/ConfigurationParserTest.java	2009-04-21 13:37:17 UTC (rev 157)
@@ -3,6 +3,7 @@
 import org.infinispan.config.CacheLoaderManagerConfig;
 import org.infinispan.config.Configuration;
 import org.infinispan.config.ConfigurationException;
+import org.infinispan.distribution.DefaultConsistentHash;
 import org.infinispan.eviction.EvictionStrategy;
 import org.infinispan.loader.CacheStoreConfig;
 import org.infinispan.loader.decorators.SingletonStoreConfig;
@@ -10,7 +11,6 @@
 import org.infinispan.loader.file.FileCacheStoreConfig;
 import org.infinispan.lock.IsolationLevel;
 import org.infinispan.transaction.GenericTransactionManagerLookup;
-import org.infinispan.distribution.DefaultConsistentHash;
 import org.testng.annotations.Test;
 import org.w3c.dom.Element;
 
@@ -309,27 +309,27 @@
       String xml = "<clustering mode=\"d\"><sync/><async/></clustering>";
       try {
          parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
+         assert false : "Should fail";
       } catch (ConfigurationException ce) {
          // expected
       }
 
       xml = "<clustering mode=\"d\"><stateRetrieval /></clustering>";
-
+      Configuration c = new Configuration();
+      parser.configureClustering(XmlConfigHelper.stringToElement(xml), c);
       try {
-         parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
-      } catch (ConfigurationException ce) {
-         // expected
+         c.assertValid();
+         assert false : "Should fail";
+      } catch (ConfigurationException expected) {
       }
 
       xml = "<clustering mode=\"d\"><stateRetrieval fetchInMemoryState=\"true\"/></clustering>";
-
+      c = new Configuration();
+      parser.configureClustering(XmlConfigHelper.stringToElement(xml), c);
       try {
-         parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
-      } catch (ConfigurationException ce) {
-         // expected
+         c.assertValid();
+         assert false : "Should fail";
+      } catch (ConfigurationException expected) {
       }
 
       xml = "<clustering mode=\"d\"><stateRetrieval fetchInMemoryState=\"false\"/></clustering>";
@@ -339,7 +339,7 @@
 
       try {
          parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
+         assert false : "Should fail";
       } catch (ConfigurationException ce) {
          // expected
       }
@@ -348,16 +348,16 @@
 
       try {
          parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
+         assert false : "Should fail";
       } catch (ConfigurationException ce) {
          // expected
       }
 
-xml = "<clustering mode=\"r\"><hash /></clustering>";
+      xml = "<clustering mode=\"r\"><hash /></clustering>";
 
       try {
          parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
+         assert false : "Should fail";
       } catch (ConfigurationException ce) {
          // expected
       }
@@ -366,12 +366,9 @@
 
       try {
          parser.configureClustering(XmlConfigHelper.stringToElement(xml), new Configuration());
-         assert false: "Should fail";
+         assert false : "Should fail";
       } catch (ConfigurationException ce) {
          // expected
       }
-
-
-
    }
 }




More information about the infinispan-commits mailing list