You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/03/19 08:10:54 UTC

svn commit: r755861 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-slice/src/main/java/org/apache/openjpa/slice/ openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/ openjpa-slice/src/test/java/org/apache/...

Author: ppoddar
Date: Thu Mar 19 07:10:53 2009
New Revision: 755861

URL: http://svn.apache.org/viewvc?rev=755861&view=rev
Log:
OPENJPA-985: Support dynamic addition of slices.

Added:
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBroker.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerFactory.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedStoreManager.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCStoreManager.java
      - copied, changed from r755481, openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
Removed:
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
    openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
    openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
    openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java Thu Mar 19 07:10:53 2009
@@ -128,8 +128,8 @@
     /**
      * Synchronize the mappings of the classes listed in the configuration.
      */
-    protected void synchronizeMappings(ClassLoader loader) {
-        JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
+    protected void synchronizeMappings(ClassLoader loader, 
+        JDBCConfiguration conf) {
         String action = conf.getSynchronizeMappings();
         if (StringUtils.isEmpty(action))
             return;
@@ -158,4 +158,8 @@
         }
         tool.record();
     }
+    
+    protected void synchronizeMappings(ClassLoader loader) {
+        synchronizeMappings(loader, (JDBCConfiguration) getConfiguration());
+    }
 }

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBroker.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBroker.java?rev=755861&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBroker.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBroker.java Thu Mar 19 07:10:53 2009
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Map;
+
+import org.apache.openjpa.kernel.Broker;
+
+/**
+ * Extension to Broker to allow dynamically add/remove slices.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public interface DistributedBroker extends Broker {
+    /**
+     * Adds the given slice with the given properties. This newly added slice
+     * will participate in the current and subsequent transaction.
+     * 
+     * @param name logical name of the to be added slice. Must be different from
+     * any currently available slices.
+     * @see DistributedConfiguration#getAvailableSliceNames()
+     * 
+     * @param properties key-value pair of configuration for the slice to be
+     * added. The keys must have openjpa.slice.<name>.* as prefix.
+     * 
+     * @see DistributedConfiguration#addSlice(String, Map)
+     */
+    Slice addSlice(String name, Map properties);
+}

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerFactory.java?rev=755861&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerFactory.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerFactory.java Thu Mar 19 07:10:53 2009
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Map;
+
+import org.apache.openjpa.kernel.BrokerFactory;
+
+/**
+ * Extension to BrokerFactory to allow dynamically add/remove slices.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public interface DistributedBrokerFactory extends BrokerFactory {
+    /**
+     * Adds the given slice with the given properties. This newly added slice
+     * will be configured to brokers constructed by this factory after this
+     * call.
+     * 
+     * @param name logical name of the to be added slice. Must be different from
+     * any currently available slices.
+     * @see DistributedConfiguration#getAvailableSliceNames()
+     * 
+     * @param properties key-value pair of configuration for the slice to be
+     * added. The keys must have openjpa.slice.<name>.* as prefix.
+     * 
+     * @see DistributedConfiguration#addSlice(String, Map)
+     */
+    public Slice addSlice(String name, Map properties);
+}

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java Thu Mar 19 07:10:53 2009
@@ -18,6 +18,8 @@
  */
 package org.apache.openjpa.slice;
 
+import java.util.Map;
+
 import org.apache.openjpa.kernel.FinalizingBrokerImpl;
 import org.apache.openjpa.kernel.OpCallbacks;
 import org.apache.openjpa.kernel.OpenJPAStateManager;
@@ -36,7 +38,8 @@
  * 
  */
 @SuppressWarnings("serial")
-public class DistributedBrokerImpl extends FinalizingBrokerImpl {
+public class DistributedBrokerImpl extends FinalizingBrokerImpl 
+    implements DistributedBroker {
 	private transient String _rootSlice;
 	private transient DistributedConfiguration _conf;
 	private final ReentrantSliceLock _lock;
@@ -55,6 +58,18 @@
     	}
         return _conf;
     }
+    
+    public DistributedStoreManager getDistributedStoreManager() {
+        return (DistributedStoreManager)getStoreManager().getInnermostDelegate();
+    }
+    
+    public Slice addSlice(String name, Map properties) {
+        Slice slice = ((DistributedBrokerFactory)getBrokerFactory()).addSlice(
+            name, properties);
+        getDistributedStoreManager().addSlice(slice);
+        return slice;
+    }
+    
 	/**
 	 * Assigns slice identifier to the resultant StateManager as initialized by
 	 * the super class implementation. The slice identifier is decided by

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java Thu Mar 19 07:10:53 2009
@@ -19,6 +19,7 @@
 package org.apache.openjpa.slice;
 
 import java.util.List;
+import java.util.Map;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 
@@ -70,15 +71,57 @@
 	 */
 	Slice getSlice(String sliceName);
 	
-	/**
-	 * Gets the policy that governs how new instances will be distributed across
-	 * the available slices.
-	 */
-	DistributionPolicy getDistributionPolicyInstance();
+    /**
+     * Gets the policy that governs how new instances will be distributed across
+     * the available slices.
+     */
+    DistributionPolicy getDistributionPolicyInstance();
+    
+    /**
+     * Sets the policy that governs how new instances will be distributed across
+     * the available slices.
+     */
+    void setDistributionPolicyInstance(DistributionPolicy policy);
 	
-	/**
-	 * Gets the policy that governs how new replicated instances will be 
-	 * replicated across the available slices.
+    /**
+     * Gets the policy, as a plugin string, that governs how new instances will 
+     * be distributed across the available slices.
+     */
+    String getDistributionPolicy();
+    
+    /**
+     * Sets the policy, from the given plugin string, that governs how new 
+     * instances will be distributed across the available slices.
+     */
+    void setDistributionPolicy(String policy);
+
+    /**
+     * Gets the policy that governs how new replicated instances will be 
+     * replicated across the available slices.
+     */
+    ReplicationPolicy getReplicationPolicyInstance();
+    
+    /**
+     * Gets the policy, as a plugin string, that governs how new replicated 
+     * instances will be replicated across the available slices.
+     */
+    String getReplicationPolicy();
+	
+    /**
+     * Sets the policy that governs how new replicated instances will be 
+     * replicated across the available slices.
+     */
+    void setReplicationPolicyInstance(ReplicationPolicy policy);
+    
+    /**
+     * Sets the policy, from the given plugin string, that governs how new 
+     * replicated instances will be replicated across the available slices.
+     */
+    void setReplicationPolicy(String policy);
+	/**
+	 * Adds a new Slice of the given name and given properties.
+     * The given properties must have keys with prefix openjpa.slice.<name>.*
+     * where <name> is the new slice to be added.
 	 */
-	ReplicationPolicy getReplicationPolicyInstance();
+    Slice addSlice(String name, Map properties);
 }

Added: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedStoreManager.java?rev=755861&view=auto
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedStoreManager.java (added)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedStoreManager.java Thu Mar 19 07:10:53 2009
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.slice;
+
+import java.util.Map;
+
+import org.apache.openjpa.kernel.StoreManager;
+import org.apache.openjpa.slice.jdbc.SliceStoreManager;
+
+public interface DistributedStoreManager extends StoreManager {
+    /**
+     * Adds the given slice with the given properties. This newly added slice
+     * will participate in the current and subsequent transaction.
+     * 
+     * @param name logical name of the to be added slice. Must be different from
+     * any currently available slices.
+     * @see DistributedBroker#addSlice(String, Map)
+     * @see DistributedBrokerFactory#addSlice(String, Map)
+     * 
+     * @return the store manager for the newly added slice.
+     * 
+     */
+    public SliceStoreManager addSlice(Slice slice);
+
+}

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java Thu Mar 19 07:10:53 2009
@@ -84,21 +84,20 @@
         boolean modified = false;
         Log log = conf.getConfigurationLog();
         if (conf.getDistributionPolicyInstance() == null) {
-        	forceSet(PREFIX_SLICE, conf.distributionPolicyPlugin,"random", log);
+        	forceSet(conf.distributionPolicyPlugin,"random", log);
         	modified = true;
         }
         if (conf.getReplicationPolicyInstance() == null) {
-        	forceSet(PREFIX_SLICE, conf.replicationPolicyPlugin, "all", log);
+        	forceSet(conf.replicationPolicyPlugin, "all", log);
         	modified = true;
         }
         return modified;
     }
     
-    void forceSet(String prefix, Value v, String forced, Log log) {
+    void forceSet(Value v, String forced, Log log) {
     	v.setString(forced);
     	if (log.isWarnEnabled())
-        	log.warn(_loc.get("forced-set-config", 
-        		prefix+"."+v.getProperty(), forced));
+        	log.warn(_loc.get("forced-set-config", v.getProperty(), forced));
     }
     
     public Set<String> getSupportedQueryHints() {

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java Thu Mar 19 07:10:53 2009
@@ -56,7 +56,7 @@
 			targets = new String[]{((DistributionPolicy)policy).distribute 
 				(pc, actives, ctx)};
 		}
-		assertSlices(targets, pc, actives, policy);
+		assertSlices(targets, pc, conf.getActiveSliceNames(), policy);
 		return new SliceInfo(replicated, targets);
 	}
 	

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedDataSource.java Thu Mar 19 07:10:53 2009
@@ -47,6 +47,10 @@
 		master = dataSources.get(0);
 	}
 	
+	public void addDataSource(DataSource ds) {
+	    real.add(ds);
+	}
+	
 	Connection getConnection(DataSource ds) throws SQLException {
 		if (ds instanceof DecoratingDataSource)
 			return getConnection(((DecoratingDataSource)ds).getInnermostDelegate());

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java Thu Mar 19 07:10:53 2009
@@ -18,6 +18,7 @@
  */
 package org.apache.openjpa.slice.jdbc;
 
+import java.security.AccessController;
 import java.util.Map;
 
 import org.apache.openjpa.conf.OpenJPAVersion;
@@ -26,7 +27,10 @@
 import org.apache.openjpa.kernel.Bootstrap;
 import org.apache.openjpa.kernel.StoreManager;
 import org.apache.openjpa.lib.conf.ConfigurationProvider;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.slice.DistributedBrokerFactory;
+import org.apache.openjpa.slice.Slice;
 
 /**
  * A factory for distributed JDBC datastores.
@@ -35,7 +39,8 @@
  * 
  */
 @SuppressWarnings("serial")
-public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory {
+public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory 
+    implements DistributedBrokerFactory {
 	private static final Localizer _loc = 
 	    Localizer.forPackage(DistributedJDBCBrokerFactory.class);
 	/**
@@ -93,10 +98,18 @@
 	public DistributedJDBCConfiguration getConfiguration() {
 	    return (DistributedJDBCConfiguration)super.getConfiguration();
 	}
+	
+	public Slice addSlice(String name, Map properties) {
+	    Slice slice = getConfiguration().addSlice(name, properties);
+        ClassLoader loader = AccessController.doPrivileged(
+            J2DoPrivHelper.getContextClassLoaderAction());
+	    synchronizeMappings(loader, (JDBCConfiguration)slice.getConfiguration());
+	    return slice;
+	}
 
 	@Override
-	protected StoreManager newStoreManager() {
-		return new DistributedStoreManager(getConfiguration());
+	protected DistributedJDBCStoreManager newStoreManager() {
+		return new DistributedJDBCStoreManager(getConfiguration());
 	}
 	
     @Override

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java Thu Mar 19 07:10:53 2009
@@ -63,17 +63,19 @@
         implements DistributedJDBCConfiguration {
 
     private final List<Slice> _slices = new ArrayList<Slice>();
-    private List<String> _activeSliceNames = new ArrayList<String>();
     private Slice _master;
     
-    private DecoratingDataSource virtualDataSource;
+    private DistributedDataSource virtualDataSource;
     
     protected BooleanValue lenientPlugin;
     protected StringValue masterPlugin;
     protected StringListValue namesPlugin;
     public PluginValue distributionPolicyPlugin;
     public PluginValue replicationPolicyPlugin;
-
+    
+    protected Log log;
+    protected String unit;
+    
     public static final String DOT = ".";
     public static final String REGEX_DOT = "\\.";
     public static final String PREFIX_SLICE = ProductDerivation.PREFIX_SLICE + 
@@ -89,40 +91,42 @@
     public DistributedJDBCConfigurationImpl(ConfigurationProvider cp) {
         super(true, false);
         Map p = cp.getProperties();
-        String pUnit = getPersistenceUnitName(p);
-        setDiagnosticContext(pUnit);
+        log = getConfigurationLog();
+        unit = getPersistenceUnitName(p);
+        setDiagnosticContext(this, unit);
         
         brokerPlugin.setString(DistributedBrokerImpl.class.getName());
         
-        distributionPolicyPlugin = addPlugin("DistributionPolicy", true);
+        distributionPolicyPlugin = addPlugin(
+            PREFIX_SLICE + "DistributionPolicy", true);
         distributionPolicyPlugin.setAlias("random", 
         	DistributionPolicy.Default.class.getName());
         distributionPolicyPlugin.setDefault("random");
         distributionPolicyPlugin.setDynamic(true);
         
-        replicationPolicyPlugin = addPlugin
-        	("ReplicatedDistributionPolicy", true);
+        replicationPolicyPlugin = addPlugin(
+            PREFIX_SLICE + "ReplicationPolicy", true);
         replicationPolicyPlugin.setAlias("all", 
-        	ReplicationPolicy.Default.class.getName());
+            ReplicationPolicy.Default.class.getName());
         replicationPolicyPlugin.setDefault("all");
         replicationPolicyPlugin.setDynamic(true);
         
-        lenientPlugin = addBoolean("Lenient");
+        lenientPlugin = addBoolean(PREFIX_SLICE + "Lenient");
         
-        masterPlugin = addString("Master");
+        masterPlugin = addString(PREFIX_SLICE + "Master");
         
-        namesPlugin = addStringList("Names");
+        namesPlugin = addStringList(PREFIX_SLICE + "Names");
         
         setSlices(p);
     }
     
     private String getPersistenceUnitName(Map p) {
-        Object unit = p.get(PREFIX_OPENJPA+id.getProperty());
+        Object unit = p.get(PREFIX_OPENJPA + id.getProperty());
         return (unit == null) ? "?" : unit.toString();
     }
     
-    private void setDiagnosticContext(String unit) {
-        LogFactory logFactory = getLogFactory();
+    private void setDiagnosticContext(OpenJPAConfiguration conf, String unit) {
+        LogFactory logFactory = conf.getLogFactory();
         if (logFactory instanceof LogFactoryImpl) {
             ((LogFactoryImpl)logFactory).setDiagnosticContext(unit);
         }
@@ -132,12 +136,12 @@
      * Gets the name of the active slices.
      */
     public List<String> getActiveSliceNames() {
-        if (_activeSliceNames.isEmpty()) {
-            for (Slice slice:_slices)
-                if (slice.isActive())
-                    _activeSliceNames.add(slice.getName());
+        List<String> result = new ArrayList<String>();
+        for (Slice slice : _slices) {
+           if (slice.isActive() && !result.contains(slice.getName()))
+              result.add(slice.getName());
         }
-        return _activeSliceNames;
+        return result;
     }
     
     /**
@@ -172,15 +176,25 @@
         return _master;
     }
 
+    public Slice getSlice(String name) {
+        return getSlice(name, false);
+    }
+    
     /**
      * Get the configuration for given slice.
+     * 
+     * @param mustExist if true an exception if raised if the given slice name
+     * is not an active slice.
      */
-    public Slice getSlice(String name) {
+    public Slice getSlice(String name, boolean mustExist) {
         for (Slice slice:_slices)
             if (slice.getName().equals(name))
                 return slice;
-        throw new UserException(_loc.get("slice-not-found", name,
+        if (mustExist) {
+            throw new UserException(_loc.get("slice-not-found", name,
                     getActiveSliceNames()));
+        }
+        return null;
     }
 
     public DistributionPolicy getDistributionPolicyInstance() {
@@ -190,32 +204,59 @@
         }
         return (DistributionPolicy) distributionPolicyPlugin.get();
     }
+    
+    public String getDistributionPolicy() {
+        if (distributionPolicyPlugin.get() == null) {
+            distributionPolicyPlugin.instantiate(DistributionPolicy.class,
+                    this, true);
+        }
+        return distributionPolicyPlugin.getString();
+    }
 
-    public void setDistributionPolicyInstance(String val) {
-    	replicationPolicyPlugin.set(val);
+    public void setDistributionPolicyInstance(DistributionPolicy policy) {
+        distributionPolicyPlugin.set(policy);
+    }
+    
+    public void setDistributionPolicy(String policy) {
+        distributionPolicyPlugin.setString(policy);
     }
 
     public ReplicationPolicy getReplicationPolicyInstance() {
         if (replicationPolicyPlugin.get() == null) {
-        	replicationPolicyPlugin.instantiate(ReplicationPolicy.class,
+            replicationPolicyPlugin.instantiate(ReplicationPolicy.class,
                     this, true);
         }
         return (ReplicationPolicy) replicationPolicyPlugin.get();
     }
+    
+    public String getReplicationPolicy() {
+        if (replicationPolicyPlugin.get() == null) {
+            replicationPolicyPlugin.instantiate(ReplicationPolicy.class,
+                    this, true);
+        }
+        return replicationPolicyPlugin.getString();
+    }
 
-    public void setReplicatedDistributionPolicyInstance(String val) {
-        distributionPolicyPlugin.set(val);
+    public void setReplicationPolicyInstance(ReplicationPolicy policy) {
+        replicationPolicyPlugin.set(policy);
+    }
+    
+    public void setReplicationPolicy(String policy) {
+        replicationPolicyPlugin.setString(policy);
     }
 
-    public Object getConnectionFactory() {
+    public DistributedDataSource getConnectionFactory() {
         if (virtualDataSource == null) {
-            DistributedDataSource ds = createDistributedDataStore();
-            virtualDataSource =
-                    DataSourceFactory.installDBDictionary(
-                            getDBDictionaryInstance(), ds, this, false);
+            virtualDataSource = createDistributedDataStore();
+            DataSourceFactory.installDBDictionary(
+                getDBDictionaryInstance(), virtualDataSource, this, false);
         }
         return virtualDataSource;
     }
+    
+    public boolean isLenient() {
+        return lenientPlugin.get();
+    }
 
     /**
      * Create a virtual DistributedDataSource as a composite of individual
@@ -224,25 +265,14 @@
      */
     private DistributedDataSource createDistributedDataStore() {
         List<DataSource> dataSources = new ArrayList<DataSource>();
-        boolean isLenient = lenientPlugin.get();
         boolean isXA = true;
         for (Slice slice : _slices) {
-            JDBCConfiguration conf = (JDBCConfiguration)slice.getConfiguration();
-            Log log = conf.getConfigurationLog();
-            String url = getConnectionInfo(conf);
-            if (log.isInfoEnabled())
-                log.info(_loc.get("slice-connect", slice, url));
             try {
-                DataSource ds = DataSourceFactory.newDataSource(conf, false);
-                DecoratingDataSource dds = new DecoratingDataSource(ds);
-                ds = DataSourceFactory.installDBDictionary(
-                        conf.getDBDictionaryInstance(), dds, conf, false);
-                if (verifyDataSource(slice, ds, conf)) {
-                    dataSources.add(ds);
-                    isXA &= isXACompliant(ds);
-                }
+                DataSource ds = createDataSource(slice);
+                dataSources.add(ds);
+                isXA &= isXACompliant(ds);
             } catch (Throwable ex) {
-                handleBadConnection(isLenient, slice, ex);
+                handleBadConnection(isLenient(), slice, ex);
             }
         }
         if (dataSources.isEmpty())
@@ -250,6 +280,21 @@
         DistributedDataSource result = new DistributedDataSource(dataSources);
         return result;
     }
+    
+    DataSource createDataSource(Slice slice) throws Exception {
+        JDBCConfiguration conf = (JDBCConfiguration)slice.getConfiguration();
+        Log log = conf.getConfigurationLog();
+        String url = getConnectionInfo(conf);
+        if (log.isInfoEnabled())
+            log.info(_loc.get("slice-connect", slice, url));
+        DataSource ds = DataSourceFactory.newDataSource(conf, false);
+        DecoratingDataSource dds = new DecoratingDataSource(ds);
+        ds = DataSourceFactory.installDBDictionary(
+                conf.getDBDictionaryInstance(), dds, conf, false);
+        verifyDataSource(slice, ds, conf);
+        
+        return ds;
+    }
 
     String getConnectionInfo(OpenJPAConfiguration conf) {
         String result = conf.getConnectionURL();
@@ -327,23 +372,27 @@
      */
     void setSlices(Map original) {
         List<String> sliceNames = findSlices(original);
-        Log log = getConfigurationLog();
         if (sliceNames.isEmpty()) {
             throw new UserException(_loc.get("slice-none-configured"));
         } 
-        String unit = getPersistenceUnitName(original);
         for (String key : sliceNames) {
-            JDBCConfiguration child = new JDBCConfigurationImpl();
-            child.fromProperties(createSliceProperties(original, key));
-            child.setId(unit+DOT+key);
-            Slice slice = new Slice(key, child);
+            Slice slice = newSlice(key, original);
             _slices.add(slice);
-            if (log.isTraceEnabled())
-                log.trace(_loc.get("slice-configuration", key, child
-                        .toProperties(false)));
         }
         setMaster(original);
     }
+    
+    protected Slice newSlice(String key, Map original) {
+        JDBCConfiguration child = new JDBCConfigurationImpl();
+        child.fromProperties(createSliceProperties(original, key));
+        child.setId(unit+DOT+key);
+        setDiagnosticContext(child, unit+DOT+key);
+        Slice slice = new Slice(key, child);
+        if (log.isTraceEnabled())
+            log.trace(_loc.get("slice-configuration", key, child
+                    .toProperties(false)));
+        return slice;
+    }
 
     /**
      * Finds the slices. If <code>openjpa.slice.Names</code> property is 
@@ -357,7 +406,7 @@
         List<String> sliceNames = new ArrayList<String>();
         
         Log log = getConfigurationLog();
-        String key = PREFIX_SLICE + namesPlugin.getProperty();
+        String key = namesPlugin.getProperty();
         boolean explicit = p.containsKey(key);
         if (explicit) {
             String[] values = p.get(key).toString().split("\\,");
@@ -454,7 +503,7 @@
      * Determine the master slice.
      */
     private void setMaster(Map original) {
-        String key = PREFIX_SLICE + masterPlugin.getProperty();
+        String key = masterPlugin.getProperty();
         Object masterSlice = original.get(key);
         Log log = getConfigurationLog();
         List<Slice> activeSlices = getSlices(null);
@@ -471,4 +520,27 @@
             _master = activeSlices.get(0);
         }
     }
+    
+    public Slice addSlice(String name, Map newProps) {
+        String prefix = PREFIX_SLICE + DOT + name + DOT;
+        for (Object key : newProps.keySet()) {
+            if (!String.class.isInstance(key) 
+             && key.toString().startsWith(prefix))
+                throw new UserException(_loc.get("slice-add-wrong-key", key));
+        }
+        Slice slice = getSlice(name);
+        if (slice != null)
+            throw new UserException(_loc.get("slice-exists", name));
+        Map<String,String> original = super.toProperties(true);
+        original.putAll(newProps);
+         slice = newSlice(name, original);
+        _slices.add(slice);
+        try {
+            virtualDataSource.addDataSource(createDataSource(slice));
+        } catch (Exception ex) {
+            handleBadConnection(false, slice, ex);
+            return null;
+        }
+        return slice;
+    }
 }

Copied: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCStoreManager.java (from r755481, openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java)
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCStoreManager.java?p2=openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCStoreManager.java&p1=openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java&r1=755481&r2=755861&rev=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCStoreManager.java Thu Mar 19 07:10:53 2009
@@ -56,7 +56,9 @@
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.slice.DistributedStoreManager;
 import org.apache.openjpa.slice.ProductDerivation;
+import org.apache.openjpa.slice.Slice;
 import org.apache.openjpa.slice.SliceImplHelper;
 import org.apache.openjpa.slice.SliceInfo;
 import org.apache.openjpa.slice.SliceThread;
@@ -73,12 +75,13 @@
  * @author Pinaki Poddar
  * 
  */
-class DistributedStoreManager extends JDBCStoreManager {
+class DistributedJDBCStoreManager extends JDBCStoreManager 
+    implements DistributedStoreManager {
     private final List<SliceStoreManager> _slices;
     private JDBCStoreManager _master;
     private final DistributedJDBCConfiguration _conf;
     private static final Localizer _loc =
-            Localizer.forPackage(DistributedStoreManager.class);
+            Localizer.forPackage(DistributedJDBCStoreManager.class);
 
     /**
      * Constructs a set of child StoreManagers each connected to a physical
@@ -88,16 +91,15 @@
      * slices. The first slice is referred as <em>master</em> and is used to
      * get Sequence based entity identifiers.
      */
-    public DistributedStoreManager(DistributedJDBCConfiguration conf) {
+    public DistributedJDBCStoreManager(DistributedJDBCConfiguration conf) {
         super();
         _conf = conf;
         _slices = new ArrayList<SliceStoreManager>();
         List<String> sliceNames = conf.getActiveSliceNames();
         for (String name : sliceNames) {
-            SliceStoreManager slice = new SliceStoreManager
-                (conf.getSlice(name));
+            SliceStoreManager slice = new SliceStoreManager(conf.getSlice(name));
             _slices.add(slice);
-            if (name.equals(conf.getMaster().getName()))
+            if (slice.getName().equals(_conf.getMaster().getName()))
                 _master = slice;
         }
     }
@@ -109,6 +111,13 @@
     public SliceStoreManager getSlice(int i) {
     	return _slices.get(i);
     }
+    
+    public SliceStoreManager addSlice(Slice slice) {
+        SliceStoreManager result = new SliceStoreManager(slice);
+        result.setContext(getContext(), (JDBCConfiguration)slice.getConfiguration());
+        _slices.add(result);
+        return result;
+    }
 
     /**
      * Decides the index of the StoreManager by first looking at the

Modified: openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java (original)
+++ openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java Thu Mar 19 07:10:53 2009
@@ -68,8 +68,8 @@
 		_queries.add(q);
 	}
 
-	public DistributedStoreManager getDistributedStore() {
-		return (DistributedStoreManager) getStore();
+	public DistributedJDBCStoreManager getDistributedStore() {
+		return (DistributedJDBCStoreManager) getStore();
 	}
 
 	public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) {

Modified: openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java (original)
+++ openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java Thu Mar 19 07:10:53 2009
@@ -19,11 +19,15 @@
 package org.apache.openjpa.slice;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
 /**
  * Tests basic create, read, update and delete operations.
  * 
@@ -304,5 +308,41 @@
         assertEquals(pc.getId(), pc2.getId());
         assertEquals(value, pc2.getValue());
     }
+    
+    public void testDynamicSlice() {
+        DistributedConfiguration conf = (DistributedConfiguration)emf.getConfiguration();
+        conf.setDistributionPolicyInstance(new DistributionPolicy() {
+            public String distribute(Object pc, List<String> slices, Object context) {
+                if (PObject.class.isInstance(pc)) {
+                    PObject o = (PObject)pc;
+                    if (o.getValue() > 50) {
+                        DistributedBroker broker = (DistributedBroker)context;
+                        Map newProps = new HashMap();
+                        newProps.put("openjpa.slice.newslice.ConnectionURL", "jdbc:derby:target/database/newslice;create=true");
+                        newProps.put("openjpa.slice.newslice.ConnectionDriverName", "org.apache.derby.jdbc.EmbeddedDriver");
+                        broker.addSlice("newslice", newProps);
+                        return "newslice";
+                    } else {
+                        return slices.get(o.getValue()%slices.size());
+                    }
+                }
+                return null;
+            }
+        
+        });
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        PObject pc1 = new PObject(); pc1.setValue(25);
+        PObject pc2 = new PObject(); pc2.setValue(55);
+        em.persist(pc1);
+        em.persist(pc2);
+        em.getTransaction().commit();
+        Object newId = em.getObjectId(pc2);
+        em.clear();
+        
+        PObject newP = em.find(PObject.class, newId);
+        assertNotNull(newP);
+        assertEquals("newslice", SlicePersistence.getSlice(newP));
+    }
 
 }

Modified: openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java?rev=755861&r1=755860&r2=755861&view=diff
==============================================================================
--- openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java (original)
+++ openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestConfiguration.java Thu Mar 19 07:10:53 2009
@@ -18,7 +18,9 @@
  */
 package org.apache.openjpa.slice;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.BrokerFactory;
@@ -60,4 +62,23 @@
         assertTrue(slices.contains("Two"));
         assertFalse(slices.contains("Three"));
     }
+    
+    public void testDynamicConfiguration() {
+        DistributedJDBCConfiguration conf =
+            (DistributedJDBCConfiguration) emf.getConfiguration();
+        List<String> slices = conf.getAvailableSliceNames();
+        assertTrue(slices.contains("One"));
+        assertTrue(slices.contains("Two"));
+        assertTrue(slices.contains("Three"));
+        BrokerFactory bf = ((EntityManagerFactoryImpl) emf).getBrokerFactory();
+        DistributedBroker broker = (DistributedBroker)bf.newBroker();
+        Map newProps = new HashMap();
+        newProps.put("openjpa.slice.newslice.ConnectionURL", "jdbc:derby:target/database/newslice;create=true");
+        newProps.put("openjpa.slice.newslice.ConnectionDriverName", "org.apache.derby.jdbc.EmbeddedDriver");
+        broker.addSlice("newslice", newProps);
+        
+        assertTrue(conf.getActiveSliceNames().contains("newslice"));
+        
+        
+    }
 }