You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2018/03/16 18:17:22 UTC
qpid-broker-j git commit: QPID-7197: [Broker-J] Address review
comments
Repository: qpid-broker-j
Updated Branches:
refs/heads/master c05dfbd52 -> bad76bc36
QPID-7197: [Broker-J] Address review comments
* Verify that children of the object being deleted are not referenced
* Fix exception message thrown when object is referenced
Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/bad76bc3
Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/bad76bc3
Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/bad76bc3
Branch: refs/heads/master
Commit: bad76bc362ec2d272e8cb1b5136a7d0d21909536
Parents: c05dfbd
Author: Alex Rudyy <or...@apache.org>
Authored: Fri Mar 16 18:17:12 2018 +0000
Committer: Alex Rudyy <or...@apache.org>
Committed: Fri Mar 16 18:17:12 2018 +0000
----------------------------------------------------------------------
.../server/model/AbstractConfiguredObject.java | 26 +++++---
.../hierarchy/AbstractConfiguredObjectTest.java | 65 +++++++++++++++++---
.../TestAbstractInstrumentPanelImpl.java | 54 ++++++++++++++++
.../hierarchy/TestAbstractSensorImpl.java | 2 +-
.../TestDigitalInstrumentPanelImpl.java | 41 ++++++++++++
.../hierarchy/TestInstrumentPanel.java | 28 +++++++++
.../model/testmodels/hierarchy/TestModel.java | 4 +-
.../hierarchy/TestTemperatureSensorImpl.java | 2 +-
8 files changed, 203 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
index 3fe5684..4ed5865 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
@@ -2227,7 +2227,7 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
ConfiguredObject<?> proxyForValidation = createProxyForValidation(attributes);
authoriseSetAttributes(proxyForValidation, attributes);
validateChange(proxyForValidation, attributes.keySet());
- validateReferences(getHierarchyRoot(this), this);
+ checkReferencesToObjectAndItsChildren(getHierarchyRoot(this), this);
// for DELETED state we should invoke transition method first to make sure that object can be deleted.
// If method results in exception being thrown due to various integrity violations
@@ -2246,6 +2246,16 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
return deleteNoChecks();
}
+ private void checkReferencesToObjectAndItsChildren(final ConfiguredObject<?> root,
+ final ConfiguredObject<?> lookupReference)
+ {
+ getModel().getChildTypes(lookupReference.getCategoryClass())
+ .forEach(childClass -> lookupReference.getChildren(childClass)
+ .forEach(child -> checkReferencesToObjectAndItsChildren(root,
+ child)));
+ checkReferences(root, lookupReference);
+ }
+
private ConfiguredObject<?> getHierarchyRoot(final AbstractConfiguredObject<X> o)
{
ConfiguredObject<?> object = o;
@@ -2267,21 +2277,23 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
return managesChildren(object.getCategoryClass()) || managesChildren(object.getTypeClass());
}
- private void validateReferences(final ConfiguredObject<?> object,
- final ConfiguredObject<?> lookupReference)
+ private void checkReferences(final ConfiguredObject<?> object,
+ final ConfiguredObject<?> lookupReference)
{
if (hasReference(object, lookupReference))
{
- throw new IntegrityViolationException(String.format("Configured object %s is referred by %s",
- lookupReference,
- object));
+ throw new IntegrityViolationException(String.format("%s '%s' is in use by %s '%s'",
+ lookupReference.getCategoryClass().getSimpleName(),
+ lookupReference.getName(),
+ object.getCategoryClass().getSimpleName(),
+ object.getName()));
}
if (!managesChildren(object))
{
getModel().getChildTypes(object.getCategoryClass())
.forEach(childClass -> object.getChildren(childClass)
- .forEach(child -> validateReferences(child, lookupReference)));
+ .forEach(child -> checkReferences(child, lookupReference)));
}
}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
index efb0407..775174c 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
@@ -503,10 +503,15 @@ public class AbstractConfiguredObjectTest extends QpidTestCase
carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
TestCar car1 = _model.getObjectFactory().create(TestCar.class, carAttributes, null);
+ Map<String, Object> instrumentPanelAttributes = new HashMap<>();
+ instrumentPanelAttributes.put(ConfiguredObject.NAME, "instrumentPanel");
+ instrumentPanelAttributes.put(ConfiguredObject.TYPE, TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE);
+ TestInstrumentPanel instrumentPanel = (TestInstrumentPanel) car1.createChild(TestInstrumentPanel.class, instrumentPanelAttributes);
+
Map<String, Object> sensorAttributes = new HashMap<>();
sensorAttributes.put(ConfiguredObject.NAME, "sensor");
sensorAttributes.put(ConfiguredObject.TYPE, TestTemperatureSensorImpl.TEST_TEMPERATURE_SENSOR_TYPE);
- TestSensor sensor = (TestSensor) car1.createChild(TestSensor.class, sensorAttributes);
+ TestSensor sensor = (TestSensor) instrumentPanel.createChild(TestSensor.class, sensorAttributes);
Map<String, Object> engineAttributes = new HashMap<>();
engineAttributes.put(ConfiguredObject.NAME, "engine");
@@ -517,7 +522,7 @@ public class AbstractConfiguredObjectTest extends QpidTestCase
try
{
sensor.delete();
- fail("Referred engine cannot be deleted");
+ fail("Referred sensor cannot be deleted");
}
catch (IntegrityViolationException e)
{
@@ -532,15 +537,20 @@ public class AbstractConfiguredObjectTest extends QpidTestCase
carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
TestCar car1 = _model.getObjectFactory().create(TestCar.class, carAttributes, null);
+ Map<String, Object> instrumentPanelAttributes = new HashMap<>();
+ instrumentPanelAttributes.put(ConfiguredObject.NAME, "instrumentPanel");
+ instrumentPanelAttributes.put(ConfiguredObject.TYPE, TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE);
+ TestInstrumentPanel instrumentPanel = (TestInstrumentPanel) car1.createChild(TestInstrumentPanel.class, instrumentPanelAttributes);
+
Map<String, Object> sensorAttributes = new HashMap<>();
sensorAttributes.put(ConfiguredObject.NAME, "sensor1");
sensorAttributes.put(ConfiguredObject.TYPE, TestTemperatureSensorImpl.TEST_TEMPERATURE_SENSOR_TYPE);
- TestSensor sensor1 = (TestSensor) car1.createChild(TestSensor.class, sensorAttributes);
+ TestSensor sensor1 = (TestSensor) instrumentPanel.createChild(TestSensor.class, sensorAttributes);
sensorAttributes = new HashMap<>();
sensorAttributes.put(ConfiguredObject.NAME, "sensor2");
sensorAttributes.put(ConfiguredObject.TYPE, TestTemperatureSensorImpl.TEST_TEMPERATURE_SENSOR_TYPE);
- TestSensor sensor2 = (TestSensor) car1.createChild(TestSensor.class, sensorAttributes);
+ TestSensor sensor2 = (TestSensor) instrumentPanel.createChild(TestSensor.class, sensorAttributes);
Map<String, Object> engineAttributes = new HashMap<>();
engineAttributes.put(ConfiguredObject.NAME, "engine");
@@ -551,7 +561,7 @@ public class AbstractConfiguredObjectTest extends QpidTestCase
try
{
sensor1.delete();
- fail("Referred engine cannot be deleted");
+ fail("Referred sensor cannot be deleted");
}
catch (IntegrityViolationException e)
{
@@ -566,16 +576,55 @@ public class AbstractConfiguredObjectTest extends QpidTestCase
carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
TestCar car1 = _model.getObjectFactory().create(TestCar.class, carAttributes, null);
+ Map<String, Object> instrumentPanelAttributes = new HashMap<>();
+ instrumentPanelAttributes.put(ConfiguredObject.NAME, "instrumentPanel");
+ instrumentPanelAttributes.put(ConfiguredObject.TYPE, TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE);
+ TestInstrumentPanel instrumentPanel = (TestInstrumentPanel) car1.createChild(TestInstrumentPanel.class, instrumentPanelAttributes);
+
Map<String, Object> sensorAttributes = new HashMap<>();
sensorAttributes.put(ConfiguredObject.NAME, "sensor1");
sensorAttributes.put(ConfiguredObject.TYPE, TestTemperatureSensorImpl.TEST_TEMPERATURE_SENSOR_TYPE);
- TestSensor sensor1 = (TestSensor) car1.createChild(TestSensor.class, sensorAttributes);
+ TestSensor sensor1 = (TestSensor) instrumentPanel.createChild(TestSensor.class, sensorAttributes);
- assertEquals("Unexpected number of sensors after creation", 1, car1.getChildren(TestSensor.class).size());
+ assertEquals("Unexpected number of sensors after creation", 1, instrumentPanel.getChildren(TestSensor.class).size());
sensor1.delete();
- assertEquals("Unexpected number of sensors after deletion", 0, car1.getChildren(TestSensor.class).size());
+ assertEquals("Unexpected number of sensors after deletion", 0, instrumentPanel.getChildren(TestSensor.class).size());
+ }
+
+ public void testDeleteConfiguredObjectWithReferredChildren()
+ {
+ Map<String, Object> carAttributes = new HashMap<>();
+ carAttributes.put(ConfiguredObject.NAME, "car");
+ carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
+ TestCar car1 = _model.getObjectFactory().create(TestCar.class, carAttributes, null);
+
+ Map<String, Object> instrumentPanelAttributes = new HashMap<>();
+ instrumentPanelAttributes.put(ConfiguredObject.NAME, "instrumentPanel");
+ instrumentPanelAttributes.put(ConfiguredObject.TYPE, TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE);
+ TestInstrumentPanel instrumentPanel = (TestInstrumentPanel) car1.createChild(TestInstrumentPanel.class, instrumentPanelAttributes);
+
+ Map<String, Object> sensorAttributes = new HashMap<>();
+ sensorAttributes.put(ConfiguredObject.NAME, "sensor");
+ sensorAttributes.put(ConfiguredObject.TYPE, TestTemperatureSensorImpl.TEST_TEMPERATURE_SENSOR_TYPE);
+ TestSensor sensor = (TestSensor) instrumentPanel.createChild(TestSensor.class, sensorAttributes);
+
+ Map<String, Object> engineAttributes = new HashMap<>();
+ engineAttributes.put(ConfiguredObject.NAME, "engine");
+ engineAttributes.put(ConfiguredObject.TYPE, TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE);
+ engineAttributes.put("temperatureSensor", sensor.getName());
+ car1.createChild(TestEngine.class, engineAttributes);
+
+ try
+ {
+ instrumentPanel.delete();
+ fail("Instrument panel cannot be deleted as it has referenced children");
+ }
+ catch (IntegrityViolationException e)
+ {
+ // pass
+ }
}
private void doDuplicateChildCheck(final String attrToDuplicate)
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
new file mode 100644
index 0000000..5ef7001
--- /dev/null
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractInstrumentPanelImpl.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.model.testmodels.hierarchy;
+
+import java.util.Map;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.StateTransition;
+
+public class TestAbstractInstrumentPanelImpl<X extends TestAbstractInstrumentPanelImpl<X>> extends AbstractConfiguredObject<X>
+ implements TestInstrumentPanel<X>
+{
+
+ protected TestAbstractInstrumentPanelImpl(final TestCar<?> parent,
+ final Map<String, Object> attributes)
+ {
+ super(parent, attributes);
+ }
+
+ @Override
+ protected void logOperation(final String operation)
+ {
+
+ }
+
+ @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
+ private ListenableFuture<Void> onActivate()
+ {
+ setState(State.ACTIVE);
+ return Futures.immediateFuture(null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
index 82431b3..dc41c23 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractSensorImpl.java
@@ -33,7 +33,7 @@ public class TestAbstractSensorImpl<X extends TestAbstractSensorImpl<X>> extends
implements TestSensor<X>
{
- protected TestAbstractSensorImpl(final TestCar<?> parent,
+ protected TestAbstractSensorImpl(final TestInstrumentPanel<?> parent,
final Map<String, Object> attributes)
{
super(parent, attributes);
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestDigitalInstrumentPanelImpl.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestDigitalInstrumentPanelImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestDigitalInstrumentPanelImpl.java
new file mode 100644
index 0000000..e7f1f17
--- /dev/null
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestDigitalInstrumentPanelImpl.java
@@ -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.qpid.server.model.testmodels.hierarchy;
+
+import java.util.Map;
+
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
+
+@ManagedObject(category = false,
+ type = TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE)
+public class TestDigitalInstrumentPanelImpl extends TestAbstractInstrumentPanelImpl<TestDigitalInstrumentPanelImpl>
+ implements TestInstrumentPanel<TestDigitalInstrumentPanelImpl>
+{
+
+ public static final String TEST_DIGITAL_INSTRUMENT_PANEL_TYPE = "digital";
+
+ @ManagedObjectFactoryConstructor
+ protected TestDigitalInstrumentPanelImpl(final Map<String, Object> attributes, final TestCar<?> parent)
+ {
+ super(parent, attributes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestInstrumentPanel.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestInstrumentPanel.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestInstrumentPanel.java
new file mode 100644
index 0000000..190a129
--- /dev/null
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestInstrumentPanel.java
@@ -0,0 +1,28 @@
+package org.apache.qpid.server.model.testmodels.hierarchy;/*
+ *
+ * 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.
+ *
+ */
+
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ManagedObject;
+
+@ManagedObject(category = true, defaultType = TestDigitalInstrumentPanelImpl.TEST_DIGITAL_INSTRUMENT_PANEL_TYPE)
+public interface TestInstrumentPanel<X extends TestInstrumentPanel<X>> extends ConfiguredObject<X>
+{
+}
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestModel.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestModel.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestModel.java
index 08d057d..a8c9ca4 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestModel.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestModel.java
@@ -83,8 +83,8 @@ public class TestModel extends Model
public Collection<Class<? extends ConfiguredObject>> getChildTypes(final Class<? extends ConfiguredObject> parent)
{
return TestCar.class.isAssignableFrom(parent)
- ? Arrays.asList(TestEngine.class, TestSensor.class)
- : Collections.emptySet();
+ ? Arrays.asList(TestEngine.class, TestInstrumentPanel.class)
+ : TestInstrumentPanel.class.isAssignableFrom(parent) ? Collections.singleton(TestSensor.class) : Collections.emptySet();
}
@Override
http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bad76bc3/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestTemperatureSensorImpl.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestTemperatureSensorImpl.java b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestTemperatureSensorImpl.java
index 58c656a..f2c176b 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestTemperatureSensorImpl.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestTemperatureSensorImpl.java
@@ -33,7 +33,7 @@ public class TestTemperatureSensorImpl extends TestAbstractSensorImpl<TestTemper
public static final String TEST_TEMPERATURE_SENSOR_TYPE = "temperature";
@ManagedObjectFactoryConstructor
- protected TestTemperatureSensorImpl(final Map<String, Object> attributes,final TestCar<?> parent)
+ protected TestTemperatureSensorImpl(final Map<String, Object> attributes,final TestInstrumentPanel<?> parent)
{
super(parent, attributes);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org