You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2014/08/05 15:33:01 UTC
svn commit: r1615928 - in /qpid/trunk/qpid/java/bdbstore/src:
main/java/org/apache/qpid/server/store/berkeleydb/
main/java/org/apache/qpid/server/store/berkeleydb/replication/
test/java/org/apache/qpid/server/store/berkeleydb/
Author: kwall
Date: Tue Aug 5 13:33:00 2014
New Revision: 1615928
URL: http://svn.apache.org/r1615928
Log:
QPID-5962: [Java Broker] Prevent two or more BDB virtual host or virtual hosts nodes sharing the same JE environment path
Added:
qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistry.java
qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistryTest.java
Modified:
qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java
qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java
Added: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistry.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistry.java?rev=1615928&view=auto
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistry.java (added)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistry.java Tue Aug 5 13:33:00 2014
@@ -0,0 +1,88 @@
+/*
+ * 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.qpid.server.store.berkeleydb;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.qpid.server.store.StoreException;
+
+/**
+ * JE permits the same environment to opened for write many times from within the same JVM.
+ * The Java Broker needs to disallow this as the stores of many VHNs or many VH
+ */
+public class EnvHomeRegistry
+{
+ private static final EnvHomeRegistry _instance = new EnvHomeRegistry();
+ private final Set<String> _canonicalNames = new HashSet<>();
+
+ public static final EnvHomeRegistry getInstance()
+ {
+ return _instance;
+ }
+
+ // default for unit testing
+ EnvHomeRegistry()
+ {
+ super();
+ }
+
+ public synchronized void registerHome(final File home) throws StoreException
+ {
+ if (home == null)
+ {
+ throw new IllegalArgumentException("home parameter cannot be null");
+ }
+
+ String canonicalForm = getCanonicalForm(home);
+ if (_canonicalNames.contains(canonicalForm))
+ {
+ throw new IllegalArgumentException("JE Home " + home + " is already in use");
+ }
+ _canonicalNames.add(canonicalForm);
+ }
+
+
+ public synchronized void deregisterHome(final File home) throws StoreException
+ {
+ if (home == null)
+ {
+ throw new IllegalArgumentException("home parameter cannot be null");
+ }
+
+ String canonicalForm = getCanonicalForm(home);
+ _canonicalNames.remove(canonicalForm);
+ }
+
+ private String getCanonicalForm(final File home)
+ {
+ try
+ {
+ return home.getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ throw new StoreException("Failed to resolve " + home + " into canonical form", e);
+ }
+ }
+
+}
Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java?rev=1615928&r1=1615927&r2=1615928&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java Tue Aug 5 13:33:00 2014
@@ -49,6 +49,7 @@ public class StandardEnvironmentFacade i
private Environment _environment;
private final Committer _committer;
+ private final File _environmentPath;
public StandardEnvironmentFacade(StandardEnvironmentConfiguration configuration)
{
@@ -59,12 +60,12 @@ public class StandardEnvironmentFacade i
LOGGER.info("Creating environment at environment path " + _storePath);
}
- File environmentPath = new File(_storePath);
- if (!environmentPath.exists())
+ _environmentPath = new File(_storePath);
+ if (!_environmentPath.exists())
{
- if (!environmentPath.mkdirs())
+ if (!_environmentPath.mkdirs())
{
- throw new IllegalArgumentException("Environment path " + environmentPath + " could not be read or created. "
+ throw new IllegalArgumentException("Environment path " + _environmentPath + " could not be read or created. "
+ "Ensure the path is correct and that the permissions are correct.");
}
}
@@ -92,7 +93,20 @@ public class StandardEnvironmentFacade i
envConfig.setExceptionListener(new LoggingAsyncExceptionListener());
- _environment = new Environment(environmentPath, envConfig);
+ EnvHomeRegistry.getInstance().registerHome(_environmentPath);
+ boolean success = false;
+ try
+ {
+ _environment = new Environment(_environmentPath, envConfig);
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ EnvHomeRegistry.getInstance().deregisterHome(_environmentPath);
+ }
+ }
_committer = new CoalescingCommiter(name, this);
_committer.start();
@@ -135,7 +149,14 @@ public class StandardEnvironmentFacade i
}
finally
{
- closeEnvironment();
+ try
+ {
+ closeEnvironment();
+ }
+ finally
+ {
+ EnvHomeRegistry.getInstance().deregisterHome(_environmentPath);
+ }
}
}
Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java?rev=1615928&r1=1615927&r2=1615928&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java Tue Aug 5 13:33:00 2014
@@ -57,7 +57,23 @@ import com.sleepycat.je.Sequence;
import com.sleepycat.je.SequenceConfig;
import com.sleepycat.je.Transaction;
import com.sleepycat.je.TransactionConfig;
-import com.sleepycat.je.rep.*;
+import com.sleepycat.je.rep.AppStateMonitor;
+import com.sleepycat.je.rep.InsufficientAcksException;
+import com.sleepycat.je.rep.InsufficientLogException;
+import com.sleepycat.je.rep.InsufficientReplicasException;
+import com.sleepycat.je.rep.NetworkRestore;
+import com.sleepycat.je.rep.NetworkRestoreConfig;
+import com.sleepycat.je.rep.NodeState;
+import com.sleepycat.je.rep.NodeType;
+import com.sleepycat.je.rep.RepInternal;
+import com.sleepycat.je.rep.ReplicatedEnvironment;
+import com.sleepycat.je.rep.ReplicationConfig;
+import com.sleepycat.je.rep.ReplicationGroup;
+import com.sleepycat.je.rep.ReplicationMutableConfig;
+import com.sleepycat.je.rep.ReplicationNode;
+import com.sleepycat.je.rep.RestartRequiredException;
+import com.sleepycat.je.rep.StateChangeEvent;
+import com.sleepycat.je.rep.StateChangeListener;
import com.sleepycat.je.rep.util.DbPing;
import com.sleepycat.je.rep.util.ReplicationGroupAdmin;
import com.sleepycat.je.rep.utilint.HostPortPair;
@@ -71,6 +87,7 @@ import org.codehaus.jackson.map.ObjectMa
import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.store.StoreFuture;
import org.apache.qpid.server.store.berkeleydb.CoalescingCommiter;
+import org.apache.qpid.server.store.berkeleydb.EnvHomeRegistry;
import org.apache.qpid.server.store.berkeleydb.EnvironmentFacade;
import org.apache.qpid.server.store.berkeleydb.LoggingAsyncExceptionListener;
import org.apache.qpid.server.util.DaemonThreadFactory;
@@ -132,7 +149,6 @@ public class ReplicatedEnvironmentFacade
put(ReplicationConfig.LOG_FLUSH_TASK_INTERVAL, "1 min");
}});
- public static final String TYPE = "BDB-HA";
private static final String PERMITTED_NODE_LIST = "permittedNodes";
private final ReplicatedEnvironmentConfiguration _configuration;
@@ -183,7 +199,20 @@ public class ReplicatedEnvironmentFacade
_groupChangeExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() + 1, new DaemonThreadFactory("Group-Change-Learner:" + _prettyGroupNodeName));
// create environment in a separate thread to avoid renaming of the current thread by JE
- _environment = createEnvironment(true);
+ EnvHomeRegistry.getInstance().registerHome(_environmentDirectory);
+ boolean success = false;
+ try
+ {
+ _environment = createEnvironment(true);
+ success = true;
+ }
+ finally
+ {
+ if (!success)
+ {
+ EnvHomeRegistry.getInstance().deregisterHome(_environmentDirectory);
+ }
+ }
populateExistingRemoteReplicationNodes();
_groupChangeExecutor.submit(new RemoteNodeStateLearner());
}
@@ -234,8 +263,8 @@ public class ReplicatedEnvironmentFacade
public void close()
{
if (_state.compareAndSet(State.OPENING, State.CLOSING) ||
- _state.compareAndSet(State.OPEN, State.CLOSING) ||
- _state.compareAndSet(State.RESTARTING, State.CLOSING) )
+ _state.compareAndSet(State.OPEN, State.CLOSING) ||
+ _state.compareAndSet(State.RESTARTING, State.CLOSING) )
{
try
{
@@ -258,7 +287,14 @@ public class ReplicatedEnvironmentFacade
}
finally
{
- closeEnvironment();
+ try
+ {
+ closeEnvironment();
+ }
+ finally
+ {
+ EnvHomeRegistry.getInstance().deregisterHome(_environmentDirectory);
+ }
}
}
finally
@@ -714,13 +750,13 @@ public class ReplicatedEnvironmentFacade
String newMaster = admin.transferMaster(Collections.singleton(nodeName), MASTER_TRANSFER_TIMEOUT, TimeUnit.MILLISECONDS, true);
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("The mastership has been transfered to " + newMaster);
+ LOGGER.debug("The mastership has been transferred to " + newMaster);
}
}
catch (DatabaseException e)
{
- LOGGER.warn("Exception on transfering the mastership to " + _prettyGroupNodeName
- + " Master transfer timeout : " + MASTER_TRANSFER_TIMEOUT, e);
+ LOGGER.warn("Exception on transferring the mastership to " + _prettyGroupNodeName
+ + " Master transfer timeout : " + MASTER_TRANSFER_TIMEOUT, e);
throw e;
}
return null;
Added: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistryTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistryTest.java?rev=1615928&view=auto
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistryTest.java (added)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/EnvHomeRegistryTest.java Tue Aug 5 13:33:00 2014
@@ -0,0 +1,68 @@
+/*
+ * 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.qpid.server.store.berkeleydb;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class EnvHomeRegistryTest extends TestCase
+{
+
+ private final EnvHomeRegistry _ehr = new EnvHomeRegistry();
+
+ public void testDuplicateEnvHomeRejected() throws Exception
+ {
+ File home = new File(QpidTestCase.TMP_FOLDER, getName());
+
+ _ehr.registerHome(home);
+ try
+ {
+ _ehr.registerHome(home);
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+ }
+
+ public void testUniqueEnvHomesAllowed() throws Exception
+ {
+ File home1 = new File(QpidTestCase.TMP_FOLDER, getName() + "1");
+ File home2 = new File(QpidTestCase.TMP_FOLDER, getName() + "2");
+
+ _ehr.registerHome(home1);
+ _ehr.registerHome(home2);
+ }
+
+ public void testReuseOfEnvHomesAllowed() throws Exception
+ {
+ File home = new File(QpidTestCase.TMP_FOLDER, getName() + "1");
+
+ _ehr.registerHome(home);
+
+ _ehr.deregisterHome(home);
+
+ _ehr.registerHome(home);
+ }
+}
\ No newline at end of file
Modified: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java?rev=1615928&r1=1615927&r2=1615928&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacadeTest.java Tue Aug 5 13:33:00 2014
@@ -73,6 +73,26 @@ public class StandardEnvironmentFacadeTe
assertTrue("Environment is not valid", e.isValid());
}
+ public void testSecondEnvironmentFacadeUsingSamePathRejected() throws Exception
+ {
+ EnvironmentFacade ef = createEnvironmentFacade();
+ assertNotNull("Environment should not be null", ef);
+ try
+ {
+ createEnvironmentFacade();
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+
+ ef.close();
+
+ EnvironmentFacade ef2 = createEnvironmentFacade();
+ assertNotNull("Environment should not be null", ef2);
+ }
+
public void testClose() throws Exception
{
EnvironmentFacade ef = createEnvironmentFacade();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org