You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2009/10/05 14:27:04 UTC

svn commit: r821770 [2/5] - in /qpid/branches/java-broker-0-10/qpid: ./ buildtools/buildCreator/ cpp/ cpp/bindings/qmf/ cpp/bindings/qmf/ruby/ cpp/bindings/qmf/tests/ cpp/docs/api/ cpp/examples/ cpp/examples/messaging/ cpp/include/qmf/ cpp/include/qpid...

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/UpdateClient.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/UpdateClient.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/UpdateClient.cpp Mon Oct  5 12:26:55 2009
@@ -213,7 +213,7 @@
         framing::MessageTransferBody transfer(
             framing::ProtocolVersion(), UpdateClient::UPDATE, message::ACCEPT_MODE_NONE, message::ACQUIRE_MODE_PRE_ACQUIRED);
         
-        sb.get()->send(transfer, message.payload->getFrames());
+        sb.get()->send(transfer, message.payload->getFrames(), !message.payload->isContentReleased());
         if (message.payload->isContentReleased()){
             uint16_t maxFrameSize = sb.get()->getConnection()->getNegotiatedSettings().maxFrameSize;
             uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/WatchDogPlugin.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/WatchDogPlugin.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/WatchDogPlugin.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/WatchDogPlugin.cpp Mon Oct  5 12:26:55 2009
@@ -16,6 +16,28 @@
  *
  */
 
+/**@file
+
+   The watchdog plug-in will kill the qpidd broker process if it
+   becomes stuck for longer than a configured interval.
+
+   If the watchdog plugin is loaded and the --watchdog-interval=N
+   option is set then the broker starts a watchdog process and signals
+   it every N/2 seconds.
+
+   The watchdog process runs a very simple program that starts a timer
+   for N seconds, and resets the timer to N seconds whenever it is
+   signalled by the broker. If the timer ever reaches 0 the watchdog
+   kills the broker process (with kill -9) and exits.
+
+   This is useful in a cluster setting because in some insttances
+   (e.g. while resolving an error) it's possible for a stuck process
+   to hang other cluster members that are waiting for it to send a
+   message.  Using the watchdog, the stuck process is terminated and 
+   removed fromt the cluster allowing other members to continue and
+   clients of the stuck process to fail over to other members.
+
+*/
 #include "qpid/Plugin.h"
 #include "qpid/Options.h"
 #include "qpid/log/Statement.h"

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/qpidd_watchdog.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/qpidd_watchdog.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/qpidd_watchdog.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/cluster/qpidd_watchdog.cpp Mon Oct  5 12:26:55 2009
@@ -18,6 +18,9 @@
  * under the License.
  *
  */
+
+/** @file helper executable for WatchDogPlugin.cpp */
+
 #include <sys/types.h>
 #include <sys/time.h>
 #include <signal.h>

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldTable.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldTable.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldTable.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldTable.cpp Mon Oct  5 12:26:55 2009
@@ -185,13 +185,8 @@
 bool getRawFixedWidthValue(FieldTable::ValuePtr vptr, T& value) 
 {
     if (vptr && vptr->getType() == typecode) {
-        FixedWidthValue<width>* fwv = dynamic_cast< FixedWidthValue<width>* >(&vptr->getData());
-        if (fwv) {
-            uint8_t* const octets = Endian::convertIfRequired(fwv->rawOctets(), width);
-            uint8_t* const target = reinterpret_cast<uint8_t*>(&value);
-            for (uint i = 0; i < width; ++i) target[i] = octets[i];
-            return true;
-        }
+        value = vptr->get<T>();
+        return true;
     }
     return false;
 }
@@ -370,5 +365,16 @@
         values.erase(name);
 }
 
+std::pair<FieldTable::ValueMap::iterator, bool> FieldTable::insert(const ValueMap::value_type& value)
+{
+    return values.insert(value);
+}
+
+FieldTable::ValueMap::iterator FieldTable::insert(ValueMap::iterator position, const ValueMap::value_type& value)
+{
+    return values.insert(position, value);
+}
+
+
 }
 }

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldValue.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldValue.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldValue.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/framing/FieldValue.cpp Mon Oct  5 12:26:55 2009
@@ -22,6 +22,7 @@
 #include "qpid/framing/Array.h"
 #include "qpid/framing/Buffer.h"
 #include "qpid/framing/Endian.h"
+#include "qpid/framing/List.h"
 #include "qpid/framing/reply_exceptions.h"
 
 namespace qpid {
@@ -37,6 +38,8 @@
     typeOctet = type;
     if (typeOctet == 0xA8) {
         data.reset(new EncodedValue<FieldTable>());
+    } else if (typeOctet == 0xA9) {
+        data.reset(new EncodedValue<List>());
     } else if (typeOctet == 0xAA) {
         data.reset(new EncodedValue<Array>());
     } else {    
@@ -164,10 +167,37 @@
 {
 }
 
+ListValue::ListValue(const List& l) : FieldValue(0xa9, new EncodedValue<List>(l))
+{
+}
+
 ArrayValue::ArrayValue(const Array& a) : FieldValue(0xaa, new EncodedValue<Array>(a))
 {
 }
 
+VoidValue::VoidValue() : FieldValue(0xf0, new FixedWidthValue<0>()) {}
+
+BoolValue::BoolValue(bool b) :
+    FieldValue(0x08, new FixedWidthValue<1>(b))
+{}
+
+Unsigned8Value::Unsigned8Value(uint8_t v) :
+    FieldValue(0x02, new FixedWidthValue<1>(v))
+{}
+Unsigned16Value::Unsigned16Value(uint16_t v) :
+    FieldValue(0x12, new FixedWidthValue<2>(v))
+{}
+Unsigned32Value::Unsigned32Value(uint32_t v) :
+    FieldValue(0x22, new FixedWidthValue<4>(v))
+{}
+
+Integer8Value::Integer8Value(int8_t v) :
+    FieldValue(0x01, new FixedWidthValue<1>(v))
+{}
+Integer16Value::Integer16Value(int16_t v) :
+    FieldValue(0x11, new FixedWidthValue<2>(v))
+{}
+
 void FieldValue::print(std::ostream& out) const {
     data->print(out);
     out << TypeCode(typeOctet) << '(';
@@ -177,4 +207,9 @@
     out << ')';
 }
 
+uint8_t* FieldValue::convertIfRequired(uint8_t* const octets, int width)
+{
+    return Endian::convertIfRequired(octets, width);
+}
+
 }}

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/Timer.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/Timer.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/Timer.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/Timer.cpp Mon Oct  5 12:26:55 2009
@@ -84,6 +84,7 @@
     stop();
 }
 
+// TODO AStitcher 21/08/09 The threshholds for emitting warnings are a little arbitrary
 void Timer::run()
 {
     Monitor::ScopedLock l(monitor);
@@ -111,8 +112,8 @@
                 // Warn on callback overrun
                 AbsTime end(AbsTime::now());
                 Duration overrun(tasks.top()->nextFireTime, end);
-                bool late = delay > 1 * TIME_MSEC;
-                bool overran = overrun > 1 * TIME_MSEC;
+                bool late = delay > 10 * TIME_MSEC;
+                bool overran = overrun > 2 * TIME_MSEC;
                 if (late)
                 if (overran) {
                     QPID_LOG(warning,

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp Mon Oct  5 12:26:55 2009
@@ -45,19 +45,6 @@
     typedef qpid::sys::ScopedLock<qpid::sys::Mutex>  QLock;
 
 /*
- * We keep per thread state to avoid locking overhead. The assumption is that
- * on average all the connections are serviced by all the threads so the state
- * recorded in each thread is about the same. If this turns out not to be the
- * case we could rebalance the info occasionally.  
- */
-QPID_TSS int threadReadTotal = 0;
-QPID_TSS int threadMaxRead = 0;
-QPID_TSS int threadReadCount = 0;
-QPID_TSS int threadWriteTotal = 0;
-QPID_TSS int threadWriteCount = 0;
-QPID_TSS int64_t threadMaxReadTimeNs = 2 * 1000000; // start at 2ms
-
-/*
  * The function pointers for AcceptEx and ConnectEx need to be looked up
  * at run time. Make sure this is done only once.
  */
@@ -642,12 +629,10 @@
 }
 
 void AsynchIO::readComplete(AsynchReadResult *result) {
-    ++threadReadCount;
     int status = result->getStatus();
     size_t bytes = result->getTransferred();
     if (status == 0 && bytes > 0) {
         bool restartRead = true;     // May not if receiver doesn't want more
-        threadReadTotal += bytes;
         if (readCallback)
             restartRead = readCallback(*this, result->getBuff());
         if (restartRead)
@@ -674,10 +659,8 @@
     size_t bytes = result->getTransferred();
     AsynchIO::BufferBase *buff = result->getBuff();
     if (buff != 0) {
-        ++threadWriteCount;
         writeInProgress = false;
         if (status == 0 && bytes > 0) {
-            threadWriteTotal += bytes;
             if (bytes < result->getRequested()) // Still more to go; resubmit
                 startWrite(buff);
             else

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/qpidd.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/qpidd.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/qpidd.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/qpidd.cpp Mon Oct  5 12:26:55 2009
@@ -77,7 +77,7 @@
         return broker.execute(options.get());
     }
     catch(const exception& e) {
-        QPID_LOG(critical, "Broker start-up failed: " << e.what());
+        QPID_LOG(critical, "Unexpected error: " << e.what());
     }
     return 1;
 }

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/CMakeLists.txt?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/CMakeLists.txt (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/CMakeLists.txt Mon Oct  5 12:26:55 2009
@@ -95,6 +95,7 @@
     InlineAllocator
     InlineVector
     ClientSessionTest
+    MessagingSessionTest
     SequenceSet
     StringUtils
     IncompleteMessageList
@@ -128,6 +129,7 @@
     ReplicationTest
     ClientMessageTest
     PollableCondition
+    Variant
     ${xml_tests}
     CACHE STRING "Which unit tests to build"
    )

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/FieldTable.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/FieldTable.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/FieldTable.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/FieldTable.cpp Mon Oct  5 12:26:55 2009
@@ -22,6 +22,7 @@
 #include "qpid/framing/Array.h"
 #include "qpid/framing/FieldTable.h"
 #include "qpid/framing/FieldValue.h"
+#include "qpid/framing/List.h"
 #include "qpid/sys/alloca.h"
 
 #include "unit_test.h"
@@ -86,7 +87,9 @@
 
 QPID_AUTO_TEST_CASE(testNestedValues)
 {
-    char buff[100];
+    double d = 1.2345;
+    uint32_t u = 101;
+    char buff[1000];
     {
         FieldTable a;
         FieldTable b;
@@ -94,11 +97,17 @@
         items.push_back("one");
         items.push_back("two");
         Array c(items);
+        List list;
+        list.push_back(List::ValuePtr(new Str16Value("red")));
+        list.push_back(List::ValuePtr(new Unsigned32Value(u)));
+        list.push_back(List::ValuePtr(new Str8Value("yellow")));
+        list.push_back(List::ValuePtr(new DoubleValue(d)));
         
         a.setString("id", "A");
         b.setString("id", "B");
         a.setTable("B", b);
         a.setArray("C", c);
+        a.set("my-list", FieldTable::ValuePtr(new ListValue(list)));
 
 
         Buffer wbuffer(buff, 100);
@@ -119,6 +128,27 @@
         BOOST_CHECK((uint) 2 == items.size());
         BOOST_CHECK(string("one") == items[0]);
         BOOST_CHECK(string("two") == items[1]);
+
+        List list;
+        BOOST_CHECK(a.get("my-list")->get<List>(list));
+        List::const_iterator i = list.begin();
+        BOOST_CHECK(i != list.end());
+        BOOST_CHECK_EQUAL(std::string("red"), (*i)->get<std::string>());
+
+        i++;
+        BOOST_CHECK(i != list.end());
+        BOOST_CHECK_EQUAL(u, (uint32_t) (*i)->get<int>());
+
+        i++;
+        BOOST_CHECK(i != list.end());
+        BOOST_CHECK_EQUAL(std::string("yellow"), (*i)->get<std::string>());
+
+        i++;
+        BOOST_CHECK(i != list.end());
+        BOOST_CHECK_EQUAL(d, (*i)->get<double>());
+
+        i++;
+        BOOST_CHECK(i == list.end());
     }
 }
 

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/Makefile.am
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/Makefile.am?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/Makefile.am (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/Makefile.am Mon Oct  5 12:26:55 2009
@@ -65,6 +65,7 @@
 	$(lib_client) $(lib_broker) $(lib_console)
 
 unit_test_SOURCES= unit_test.cpp unit_test.h \
+	MessagingSessionTests.cpp \
 	ClientSessionTest.cpp \
 	BrokerFixture.h SocketProxy.h \
 	exception_test.cpp \
@@ -111,7 +112,8 @@
 	FrameDecoder.cpp \
 	ReplicationTest.cpp \
 	ClientMessageTest.cpp \
-	PollableCondition.cpp
+	PollableCondition.cpp \
+	Variant.cpp
 
 if HAVE_XML
 unit_test_SOURCES+= XmlClientSessionTest.cpp

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/cli_tests.py
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/cli_tests.py?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/cli_tests.py (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/cli_tests.py Mon Oct  5 12:26:55 2009
@@ -123,6 +123,28 @@
                 found = True
         self.assertEqual(found, False)
 
+    def test_qpid_config_altex(self):
+        self.startQmf();
+        qmf = self.qmf
+        exName = "testalt"
+        altName = "amq.direct"
+
+        ret = os.system(self.command(" add exchange topic %s --alternate-exchange=%s" % (exName, altName)))
+        self.assertEqual(ret, 0)
+
+        exchanges = qmf.getObjects(_class="exchange")
+        found = False
+        for exchange in exchanges:
+            if exchange.name == altName:
+                self.assertEqual(exchange.altExchange, None)
+
+            if exchange.name == exName:
+                found = True
+                if not exchange.altExchange:
+                    self.fail("Alternate exchange not set")
+                self.assertEqual(exchange._altExchange_.name, altName)
+        self.assertEqual(found, True)
+
     def test_qpid_route(self):
         self.startQmf();
         qmf = self.qmf

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/federation.py
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/federation.py?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/federation.py (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/federation.py Mon Oct  5 12:26:55 2009
@@ -32,6 +32,17 @@
     def remote_port(self):
         return int(self.defines["remote-port"])
 
+    def verify_cleanup(self):
+        attempts = 0
+        total = len(self.qmf.getObjects(_class="bridge")) + len(self.qmf.getObjects(_class="link"))
+        while total > 0:
+            attempts += 1
+            if attempts >= 10:
+                self.fail("Bridges and links didn't clean up")
+                return
+            sleep(1)
+            total = len(self.qmf.getObjects(_class="bridge")) + len(self.qmf.getObjects(_class="link"))
+
     def test_bridge_create_and_close(self):
         self.startQmf();
         qmf = self.qmf
@@ -51,9 +62,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_pull_from_exchange(self):
         session = self.session
@@ -98,9 +107,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_push_to_exchange(self):
         session = self.session
@@ -144,9 +151,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_pull_from_queue(self):
         session = self.session
@@ -199,9 +204,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_tracing_automatic(self):
         remoteUrl = "%s:%d" % (self.remote_host(), self.remote_port())
@@ -312,9 +315,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_dynamic_fanout(self):
         session = self.session
@@ -358,9 +359,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
 
     def test_dynamic_direct(self):
@@ -405,10 +404,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
-
+        self.verify_cleanup()
 
     def test_dynamic_topic(self):
         session = self.session
@@ -452,9 +448,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
+        self.verify_cleanup()
 
     def test_dynamic_topic_reorigin(self):
         session = self.session
@@ -512,11 +506,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
-
-
+        self.verify_cleanup()
         
     def test_dynamic_direct_reorigin(self):
         session = self.session
@@ -574,11 +564,7 @@
         result = link.close()
         self.assertEqual(result.status, 0)
 
-        sleep(3)
-        self.assertEqual(len(qmf.getObjects(_class="bridge")), 0)
-        self.assertEqual(len(qmf.getObjects(_class="link")), 0)
-
-
+        self.verify_cleanup()
 
     def getProperty(self, msg, name):
         for h in msg.headers:

Modified: qpid/branches/java-broker-0-10/qpid/cpp/src/tests/perftest.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/cpp/src/tests/perftest.cpp?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/cpp/src/tests/perftest.cpp (original)
+++ qpid/branches/java-broker-0-10/qpid/cpp/src/tests/perftest.cpp Mon Oct  5 12:26:55 2009
@@ -75,6 +75,7 @@
     // Queue policy
     uint32_t queueMaxCount;
     uint64_t queueMaxSize;
+    std::string baseName;
     bool queueDurable;
 
     // Publisher
@@ -106,8 +107,8 @@
     static const std::string helpText;
     
     Opts() :
-        TestOptions(helpText),
-        setup(false), control(false), publish(false), subscribe(false),
+        TestOptions(helpText), 
+        setup(false), control(false), publish(false), subscribe(false), baseName("perftest"),
         pubs(1), count(500000), size(1024), confirm(true), durable(false), uniqueData(false), syncPub(false),
         subs(1), ack(0),
         qt(1),singleConnect(false), iterations(1), mode(SHARED), summary(false),
@@ -144,6 +145,7 @@
 
             ("queue-max-count", optValue(queueMaxCount, "N"), "queue policy: count to trigger 'flow to disk'")
             ("queue-max-size", optValue(queueMaxSize, "N"), "queue policy: accumulated size to trigger 'flow to disk'")
+            ("base-name", optValue(baseName, "NAME"), "base name used for queues or topics") 
             ("queue-durable", optValue(queueDurable, "N"), "Make queue durable (implied if durable set)")
 
             ("interval_sub", optValue(intervalSub, "ms"), ">=0 delay between msg consume")
@@ -219,6 +221,13 @@
 Opts opts;
 Connection globalConnection;
 
+std::string fqn(const std::string& name)
+{
+    ostringstream fqn;
+    fqn << opts.baseName << "_" << name;
+    return fqn.str();
+}
+
 struct Client : public Runnable {
     Connection* connection;
     Connection localConnection;
@@ -257,18 +266,18 @@
     }
 
     void run() {
-        queueInit("pub_start");
-        queueInit("pub_done");
-        queueInit("sub_ready");
-        queueInit("sub_done");
-        if (opts.iterations > 1) queueInit("sub_iteration");
+        queueInit(fqn("pub_start"));
+        queueInit(fqn("pub_done"));
+        queueInit(fqn("sub_ready"));
+        queueInit(fqn("sub_done"));
+        if (opts.iterations > 1) queueInit(fqn("sub_iteration"));
         if (opts.mode==SHARED) {
             framing::FieldTable settings;//queue policy settings
             settings.setInt("qpid.max_count", opts.queueMaxCount);
             settings.setInt("qpid.max_size", opts.queueMaxSize);
             for (size_t i = 0; i < opts.qt; ++i) {
                 ostringstream qname;
-                qname << "perftest" << i;
+                qname << opts.baseName << i;
                 queueInit(qname.str(), opts.durable || opts.queueDurable, settings); 
             }
         }
@@ -384,13 +393,13 @@
     void run() {                // Controller
         try {
             // Wait for subscribers to be ready.
-            process(opts.totalSubs, "sub_ready", bind(expect, _1, "ready"));
+            process(opts.totalSubs, fqn("sub_ready"), bind(expect, _1, "ready"));
 
             LocalQueue pubDone;
             LocalQueue subDone;
             subs.setFlowControl(0, SubscriptionManager::UNLIMITED, false);
-            subs.subscribe(pubDone, "pub_done");
-            subs.subscribe(subDone, "sub_done");
+            subs.subscribe(pubDone, fqn("pub_done"));
+            subs.subscribe(subDone, fqn("sub_done"));
 
             double txrateTotal(0);
             double mbytesTotal(0);
@@ -399,16 +408,16 @@
 
             for (size_t j = 0; j < opts.iterations; ++j) {
                 AbsTime start=now();
-                send(opts.totalPubs, "pub_start", "start"); // Start publishers
+                send(opts.totalPubs, fqn("pub_start"), "start"); // Start publishers
                 if (j) {
-                    send(opts.totalPubs, "sub_iteration", "next"); // Start subscribers on next iteration
+		    send(opts.totalPubs, fqn("sub_iteration"), "next"); // Start subscribers on next iteration
                 }
 
                 Stats pubRates;
                 Stats subRates;
 
-                process(opts.totalPubs, pubDone, "pub_done", boost::ref(pubRates));
-                process(opts.totalSubs, subDone, "sub_done", boost::ref(subRates));
+                process(opts.totalPubs, pubDone, fqn("pub_done"), boost::ref(pubRates));
+                process(opts.totalSubs, subDone, fqn("sub_done"), boost::ref(subRates));
 
                 AbsTime end=now(); 
 
@@ -497,7 +506,7 @@
             SubscriptionManager subs(session);
             LocalQueue lq;
             subs.setFlowControl(1, SubscriptionManager::UNLIMITED, true); 
-            subs.subscribe(lq, "pub_start"); 
+            subs.subscribe(lq, fqn("pub_start")); 
             
             for (size_t j = 0; j < opts.iterations; ++j) {
                 expect(lq.pop().getData(), "start");
@@ -533,7 +542,7 @@
                 double time=secs(start,end);
                 
                 // Send result to controller.
-                Message report(lexical_cast<string>(opts.count/time), "pub_done");
+                Message report(lexical_cast<string>(opts.count/time), fqn("pub_done"));
                 session.messageTransfer(arg::content=report, arg::acceptMode=1);
                 if (opts.txPub){
                     sync(session).txCommit();
@@ -587,7 +596,7 @@
             LocalQueue lq;
             Subscription subscription = subs.subscribe(lq, queue, settings);
             // Notify controller we are ready.
-            session.messageTransfer(arg::content=Message("ready", "sub_ready"), arg::acceptMode=1);
+            session.messageTransfer(arg::content=Message("ready", fqn("sub_ready")), arg::acceptMode=1);
             if (opts.txSub) {
                 if (opts.commitAsync) session.txCommit();
                 else sync(session).txCommit();
@@ -595,13 +604,13 @@
 
             LocalQueue iterationControl;
             if (opts.iterations > 1) {
-                subs.subscribe(iterationControl, "sub_iteration", SubscriptionSettings(FlowControl::messageCredit(0)));
+                subs.subscribe(iterationControl, fqn("sub_iteration"), SubscriptionSettings(FlowControl::messageCredit(0)));
             }
             
             for (size_t j = 0; j < opts.iterations; ++j) {
                 if (j > 0) {
                     //need to wait here until all subs are done
-                    session.messageFlow("sub_iteration", 0, 1); 
+                    session.messageFlow(fqn("sub_iteration"), 0, 1); 
                     iterationControl.pop();
 
                     //need to allocate some more credit for subscription
@@ -643,7 +652,7 @@
 
                 // Report to publisher.
                 Message result(lexical_cast<string>(opts.subQuota/secs(start,end)),
-                               "sub_done");
+                               fqn("sub_done"));
                 session.messageTransfer(arg::content=result, arg::acceptMode=1);
                 if (opts.txSub) sync(session).txCommit();
             }
@@ -680,7 +689,7 @@
         // Start pubs/subs for each queue/topic.
         for (size_t i = 0; i < opts.qt; ++i) {
             ostringstream key;
-            key << "perftest" << i; // Queue or topic name.
+            key << opts.baseName << i; // Queue or topic name.
             if (opts.publish) {
                 size_t n = singleProcess ? opts.pubs : 1;
                 for (size_t j = 0; j < n; ++j)  {

Propchange: qpid/branches/java-broker-0-10/qpid/java/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  5 12:26:55 2009
@@ -1,2 +1,2 @@
 /qpid/trunk/qpid:796646-796653
-/qpid/trunk/qpid/java:796196-804202
+/qpid/trunk/qpid/java:796196-807984

Propchange: qpid/branches/java-broker-0-10/qpid/java/broker/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  5 12:26:55 2009
@@ -1,2 +1,2 @@
 /qpid/branches/jmx_mc_gsoc09/qpid/java/broker:787599
-/qpid/trunk/qpid/java/broker:742626,743015,743028-743029,743304,743306,743311,743357,744113,747363,747367,747369-747370,747376,747783,747868-747870,747875,748561,748591,748641,748680,748686,749149,749282,749285,749315,749340,749572,753219-753220,753253,754934,754958,755256,757258,757270,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-804202
+/qpid/trunk/qpid/java/broker:742626,743015,743028-743029,743304,743306,743311,743357,744113,747363,747367,747369-747370,747376,747783,747868-747870,747875,748561,748591,748641,748680,748686,749149,749282,749285,749315,749340,749572,753219-753220,753253,754934,754958,755256,757258,757270,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-807984

Propchange: qpid/branches/java-broker-0-10/qpid/java/broker/bin/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  5 12:26:55 2009
@@ -1,2 +1,2 @@
 /qpid/branches/0.5-release/qpid/java/broker/bin:757268
-/qpid/trunk/qpid/java/broker/bin:753219-753220,753253,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-804202
+/qpid/trunk/qpid/java/broker/bin:753219-753220,753253,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-807984

Propchange: qpid/branches/java-broker-0-10/qpid/java/broker/bin/qpid-server.bat
            ('svn:executable' removed)

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java Mon Oct  5 12:26:55 2009
@@ -27,9 +27,9 @@
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
-import org.apache.log4j.BasicConfigurator;
 import org.apache.log4j.Logger;
-import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.xml.QpidLog4JConfigurator;
 import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.common.FixedSizeByteBufferAllocator;
 import org.apache.mina.common.IoAcceptor;
@@ -62,9 +62,11 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.BindException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.Properties;
 
 /**
  * Main entry point for AMQPD.
@@ -73,8 +75,8 @@
 @SuppressWarnings({"AccessStaticViaInstance"})
 public class Main
 {
-    private static final Logger _logger = Logger.getLogger(Main.class);
-    public static final Logger _brokerLogger = Logger.getLogger("Qpid.Broker");
+    private static Logger _logger;
+    private static Logger _brokerLogger;
 
     private static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
 
@@ -206,7 +208,7 @@
             }
             catch (InitException e)
             {
-                System.out.println(e.getMessage());
+                System.out.println("Initialisation Error : " + e.getMessage());
                 _brokerLogger.error("Initialisation Error : " + e.getMessage());
                 shutdown(1);
             }
@@ -499,7 +501,18 @@
 
     public static void main(String[] args)
     {
-
+        //if the -Dlog4j.configuration property has not been set, enable the init override
+        //to stop Log4J wondering off and picking up the first log4j.xml/properties file it
+        //finds from the classpath when we get the first Loggers
+        if(System.getProperty("log4j.configuration") == null)
+        {
+            System.setProperty("log4j.defaultInitOverride", "true");
+        }
+        
+        //now that the override status is know, we can instantiate the Loggers
+        _logger = Logger.getLogger(Main.class);
+        _brokerLogger = Logger.getLogger("Qpid.Broker");
+        
         new Main(args);
     }
 
@@ -531,7 +544,7 @@
         return ip;
     }
 
-    private void configureLogging(File logConfigFile, int logWatchTime)
+    private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException
     {
         if (logConfigFile.exists() && logConfigFile.canRead())
         {
@@ -542,18 +555,43 @@
                 System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
                                    + logWatchTime + " seconds");
                 // log4j expects the watch interval in milliseconds
-                DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000);
+                try
+                {
+                    QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
+                }
+                catch (Exception e)
+                {
+                    throw new InitException(e.getMessage(),e);
+                }
             }
             else
             {
-                DOMConfigurator.configure(logConfigFile.getAbsolutePath());
+                try
+                {
+                    QpidLog4JConfigurator.configure(logConfigFile.getPath());
+                }
+                catch (Exception e)
+                {
+                    throw new InitException(e.getMessage(),e);
+                }
             }
         }
         else
         {
             System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
-            System.err.println("Using basic log4j configuration");
-            BasicConfigurator.configure();
+            System.err.println("Using the fallback internal log4j.properties configuration");
+            
+            InputStream propsFile = this.getClass().getResourceAsStream("/log4j.properties");
+            if(propsFile == null)
+            {
+                throw new IOException("Unable to load the fallback internal log4j.properties configuration file");
+            }
+            else
+            {
+                Properties fallbackProps = new Properties();
+                fallbackProps.load(propsFile);
+                PropertyConfigurator.configure(fallbackProps);
+            }
         }
     }
 

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java Mon Oct  5 12:26:55 2009
@@ -206,11 +206,21 @@
             for (int i = 0; i < bindings.length; i++)
             {
                 String[] keyAndValue = bindings[i].split("=");
-                if (keyAndValue == null || keyAndValue.length < 2)
+                if (keyAndValue == null || keyAndValue.length == 0 || keyAndValue.length > 2)
                 {
                     throw new JMException("Format for headers binding should be \"<attribute1>=<value1>,<attribute2>=<value2>\" ");
                 }
-                bindingMap.setString(keyAndValue[0], keyAndValue[1]);
+                
+                if(keyAndValue.length ==1)
+                {
+                    //no value was given, only a key. Use an empty value
+                    //to signal match on key presence alone
+                    bindingMap.setString(keyAndValue[0], "");
+                }
+                else
+                {
+                    bindingMap.setString(keyAndValue[0], keyAndValue[1]);
+                }
             }
 
             _bindings.add(new Registration(new HeadersBinding(bindingMap), queue, new AMQShortString(binding)));

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java Mon Oct  5 12:26:55 2009
@@ -20,20 +20,28 @@
  */
 package org.apache.qpid.server.logging.management;
 
+import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.qpid.management.common.mbeans.LoggingManagement;
 import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
 import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.util.FileUtils;
 
 import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 import org.apache.log4j.xml.Log4jEntityResolver;
+import org.apache.log4j.xml.QpidLog4JConfigurator;
+import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler;
+import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -70,10 +78,12 @@
     private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class);
     private String _log4jConfigFileName;
     private int _log4jLogWatchInterval;
+    private static final String INHERITED = "INHERITED";
     private static final String[] LEVELS = new String[]{Level.ALL.toString(), Level.TRACE.toString(), 
                                                         Level.DEBUG.toString(), Level.INFO.toString(), 
                                                         Level.WARN.toString(), Level.ERROR.toString(), 
-                                                        Level.FATAL.toString(),Level.OFF.toString()};   
+                                                        Level.FATAL.toString(),Level.OFF.toString(),
+                                                        INHERITED};   
     static TabularType _loggerLevelTabularType;
     static CompositeType _loggerLevelCompositeType;
 
@@ -210,27 +220,41 @@
 
     public synchronized boolean setRuntimeRootLoggerLevel(String level)
     {
-            Level newLevel;
-            try
-            {
-                newLevel = getLevel(level);
-            }
-            catch (Exception e)
-            {
-                return false;
-            }
-            
-            _logger.info("Setting RootLogger level to " + level);
-            
-            Logger log = Logger.getRootLogger();
-            log.setLevel(newLevel);
-            
-            return true;
+        Level newLevel;
+        try
+        {
+            newLevel = getLevel(level);
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+        
+        if(newLevel == null)
+        {
+            //A null Level reference implies inheritance. Setting the runtime RootLogger 
+            //to null is catastrophic (and prevented by Log4J at startup and runtime anyway).
+            return false;
+        }
+
+        _logger.info("Setting RootLogger level to " + level);
+
+        Logger log = Logger.getRootLogger();
+        log.setLevel(newLevel);
+
+        return true;
     }
     
     //method to convert from a string to a log4j Level, throws exception if the given value is invalid
     private Level getLevel(String level) throws Exception
     {
+        if("null".equalsIgnoreCase(level) || INHERITED.equalsIgnoreCase(level))
+        {
+            //the string "null" or "inherited" signals to inherit from a parent logger,
+            //using a null Level reference for the logger.
+            return null;
+        }
+        
         Level newLevel = Level.toLevel(level);
         
         //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result.
@@ -243,137 +267,161 @@
         return newLevel;
     }
     
-    //handler to catch errors signalled by the JAXP parser and throw an appropriate exception
-    private class SaxErrorHandler implements ErrorHandler
+    //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
+    private static synchronized Document parseConfigFile(String fileName) throws IOException
     {
-        
-        public void error(SAXParseException e) throws SAXException
-        {
-            throw new SAXException("Error parsing XML file: " + e.getMessage());
-        }
-
-        public void fatalError(SAXParseException e) throws SAXException
+        try
         {
-            throw new SAXException("Fatal error parsing XML file: " + e.getMessage());
-        }
+            LOCK.lock();
 
-        public void warning(SAXParseException e) throws SAXException
-        {
-            throw new SAXException("Warning parsing XML file: " + e.getMessage());
-        }
-    }
+            //check file was specified, exists, and is readable
+            if(fileName == null)
+            {
+                _logger.warn("Provided log4j XML configuration filename is null");
+                throw new IOException("Provided log4j XML configuration filename is null");
+            }
 
-    //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
-    private synchronized Document parseConfigFile(String fileName) throws IOException
-    {
-        //check file was specified, exists, and is readable
-        if(fileName == null)
-        {
-            _logger.warn("No log4j XML configuration file has been set");
-            throw new IOException("No log4j XML configuration file has been set");
-        }
+            File configFile = new File(fileName);
 
-        File configFile = new File(fileName);
+            if (!configFile.exists())
+            {
+                _logger.warn("The log4j XML configuration file could not be found: " + fileName);
+                throw new IOException("The log4j XML configuration file could not be found");
+            }
+            else if (!configFile.canRead())
+            {
+                _logger.warn("The log4j XML configuration file is not readable: " + fileName);
+                throw new IOException("The log4j XML configuration file is not readable");
+            }
 
-        if (!configFile.exists())
-        {
-            _logger.warn("Specified log4j XML configuration file does not exist: " + fileName);
-            throw new IOException("Specified log4j XML configuration file does not exist");
-        }
-        else if (!configFile.canRead())
-        {
-            _logger.warn("Specified log4j XML configuration file is not readable: " + fileName);
-            throw new IOException("Specified log4j XML configuration file is not readable");
-        }
+            //parse it
+            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder docBuilder;
+            Document doc;
 
-        //parse it
-        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder docBuilder;
-        Document doc;
+            ErrorHandler errHandler = new QpidLog4JSaxErrorHandler();
+            try
+            {
+                docFactory.setValidating(true);
+                docBuilder = docFactory.newDocumentBuilder();
+                docBuilder.setErrorHandler(errHandler);
+                docBuilder.setEntityResolver(new Log4jEntityResolver());
+                doc = docBuilder.parse(fileName);
+            }
+            catch (ParserConfigurationException e)
+            {
+                _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e);
+                //recommended that MBeans should use java.* and javax.* exceptions only
+                throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage());
+            }
+            catch (SAXException e)
+            {
+                _logger.warn("The specified log4j XML file is invalid: " + e);
+                //recommended that MBeans should use standard java.* and javax.* exceptions only
+                throw new IOException("The specified log4j XML file is invalid: " + e.getMessage());
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Unable to parse the specified log4j XML file" + e);
+                throw new IOException("Unable to parse the specified log4j XML file: " + e.getMessage());
+            }
 
-        ErrorHandler errHandler = new SaxErrorHandler();
-        try
-        {
-            docFactory.setValidating(true);
-            docBuilder = docFactory.newDocumentBuilder();
-            docBuilder.setErrorHandler(errHandler);
-            docBuilder.setEntityResolver(new Log4jEntityResolver());
-            doc = docBuilder.parse(fileName);
-        }
-        catch (ParserConfigurationException e)
-        {
-            _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e);
-            //recommended that MBeans should use java.* and javax.* exceptions only
-            throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage());
+            return doc;
         }
-        catch (SAXException e)
-        {
-            _logger.warn("The specified log4j XML file is invalid: " + e);
-            //recommended that MBeans should use standard java.* and javax.* exceptions only
-            throw new IOException("The specified log4j XML file is invalid: " + e.getMessage());
-        }
-        catch (IOException e)
+        finally
         {
-            _logger.warn("Unable to parse the specified log4j XML file" + e);
-            throw new IOException("Unable to parse the specified log4j XML file", e);
+            LOCK.unlock();
         }
-
-        return doc;
     }
 
     
-    private synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException
+    private static synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException
     {
-        File log4jConfigFile = new File(log4jConfigFileName);
-        
-        if (!log4jConfigFile.canWrite())
-        {
-            _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile);
-            throw new IOException("Specified log4j XML configuration file is not writable");
-        }
-
-        Transformer transformer = null;
         try
         {
-            transformer = TransformerFactory.newInstance().newTransformer();
-        }
-        catch (Exception e)
-        {
-            _logger.warn("Could not create an XML transformer: " +e);
-            return false;
-        }
+            LOCK.lock();
 
-        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-        transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd");
-        DOMSource source = new DOMSource(doc);
-        
-        File tmp;
-        try
-        {
-            tmp = File.createTempFile("LogManMBeanTemp", ".tmp");
-            tmp.deleteOnExit();
-            StreamResult result = new StreamResult(tmp);
-            transformer.transform(source, result);
-        }
-        catch (TransformerException e)
-        {
-            _logger.warn("Could not transform the XML into new file: " +e);
-            return false;
-        }
-        catch (IOException e)
-        {
-            _logger.warn("Could not create the new file: " +e);
-            return false;
-        }
+            File log4jConfigFile = new File(log4jConfigFileName);
+
+            if (!log4jConfigFile.canWrite())
+            {
+                _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile);
+                throw new IOException("Specified log4j XML configuration file is not writable");
+            }
+
+            Transformer transformer = null;
+            try
+            {
+                transformer = TransformerFactory.newInstance().newTransformer();
+            }
+            catch (Exception e)
+            {
+                _logger.warn("Could not create an XML transformer: " +e);
+                return false;
+            }
 
-        // Swap temp file in to replace existing configuration file.
-        File old = new File(log4jConfigFile.getAbsoluteFile() + ".old");
-        if (old.exists())
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd");
+            DOMSource source = new DOMSource(doc);
+
+            File tmp;
+            try
+            {
+                tmp = File.createTempFile("LogManMBeanTemp", ".tmp");
+                tmp.deleteOnExit();
+                StreamResult result = new StreamResult(tmp);
+                transformer.transform(source, result);
+            }
+            catch (TransformerException e)
+            {
+                _logger.warn("Could not transform the XML into new file: " +e);
+                throw new IOException("Could not transform the XML into new file: " +e);
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Could not create the new log4j XML file: " +e);
+                throw new IOException("Could not create the new log4j XML file: " +e);
+            }
+
+            // Swap temp file in to replace existing configuration file.
+            File old = new File(log4jConfigFile.getAbsoluteFile() + ".old");
+            if (old.exists())
+            {
+                old.delete();
+            }
+            
+            try
+            {
+                if(!log4jConfigFile.renameTo(old))
+                {
+                    FileUtils.copyCheckedEx(log4jConfigFile, old);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Could not backup the existing log4j XML file: " +e);
+                throw new IOException("Could not backup the existing log4j XML file: " +e);
+            }
+            
+            try
+            {
+                if(!tmp.renameTo(log4jConfigFile))
+                {
+                    FileUtils.copyCheckedEx(tmp, log4jConfigFile);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Could not copy the new configuration into place: " +e);
+                throw new IOException("Could not copy the new configuration into place: " +e);
+            }
+            
+            return true;
+        }
+        finally
         {
-            old.delete();
+            LOCK.unlock();
         }
-        log4jConfigFile.renameTo(old);
-        return tmp.renameTo(log4jConfigFile);
     }
 
 
@@ -389,177 +437,209 @@
      * and not the only possible child element.
      */
     
-    
-    public synchronized TabularData viewConfigFileLoggerLevels() throws IOException
+    public static synchronized Map<String,String> retrieveConfigFileLoggersLevels(String fileName) throws IOException
     {
-        if (_loggerLevelTabularType == null)
+        try
         {
-            _logger.warn("TabluarData type not set up correctly");
-            return null;
-        }
-        
-        _logger.info("Getting logger levels from log4j configuration file");
-        
-        Document doc = parseConfigFile(_log4jConfigFileName);
+            LOCK.lock();
 
-        TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
+            Document doc = parseConfigFile(fileName);
 
-        //retrieve the 'category' element nodes
-        NodeList categoryElements = doc.getElementsByTagName("category");
-        
-        String categoryName;
-        String priority = null;
-        
-        for (int i = 0; i < categoryElements.getLength(); i++)
-        {
-            Element categoryElement = (Element) categoryElements.item(i);
-            categoryName = categoryElement.getAttribute("name");
+            HashMap<String,String> loggerLevelList = new HashMap<String,String>();
 
-            //retrieve the category's mandatory 'priority' or 'level' element's value.
-            //It may not be the only child node, so request by tag name.
-            NodeList priorityElements = categoryElement.getElementsByTagName("priority");
-            NodeList levelElements = categoryElement.getElementsByTagName("level");
+            //retrieve the 'category' element nodes
+            NodeList categoryElements = doc.getElementsByTagName("category");
 
-            if (priorityElements.getLength() != 0)
+            String categoryName;
+            String priority = null;
+
+            for (int i = 0; i < categoryElements.getLength(); i++)
             {
-                Element priorityElement = (Element) priorityElements.item(0);
-                priority = priorityElement.getAttribute("value").toUpperCase();
+                Element categoryElement = (Element) categoryElements.item(i);
+                categoryName = categoryElement.getAttribute("name");
+
+                //retrieve the category's mandatory 'priority' or 'level' element's value.
+                //It may not be the only child node, so request by tag name.
+                NodeList priorityElements = categoryElement.getElementsByTagName("priority");
+                NodeList levelElements = categoryElement.getElementsByTagName("level");
+
+                if (priorityElements.getLength() != 0)
+                {
+                    Element priorityElement = (Element) priorityElements.item(0);
+                    priority = priorityElement.getAttribute("value");
+                }
+                else if (levelElements.getLength() != 0)
+                {
+                    Element levelElement = (Element) levelElements.item(0);
+                    priority = levelElement.getAttribute("value");
+                }
+                else
+                {
+                    //there is no exiting priority or level to view, move onto next category/logger
+                    continue;
+                }
+
+                loggerLevelList.put(categoryName, priority);
             }
-            else if (levelElements.getLength() != 0)
+
+            //retrieve the 'logger' element nodes
+            NodeList loggerElements = doc.getElementsByTagName("logger");
+
+            String loggerName;
+            String level;
+
+            for (int i = 0; i < loggerElements.getLength(); i++)
             {
+                Element loggerElement = (Element) loggerElements.item(i);
+                loggerName = loggerElement.getAttribute("name");
+
+                //retrieve the logger's mandatory 'level' element's value
+                //It may not be the only child node, so request by tag name.
+                NodeList levelElements = loggerElement.getElementsByTagName("level");
+
                 Element levelElement = (Element) levelElements.item(0);
-                priority = levelElement.getAttribute("value").toUpperCase();
-            }
-            else
-            {
-                //there is no exiting priority or level to view, move onto next category/logger
-                continue;
-            }
+                level = levelElement.getAttribute("value");
 
-            try
-            {
-                Object[] itemData = {categoryName, priority};
-                CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
-                loggerLevelList.put(loggerData);
+                loggerLevelList.put(loggerName, level);
             }
-            catch (OpenDataException e)
+
+            return loggerLevelList;
+        }
+        finally
+        {
+            LOCK.unlock();
+        }
+    }
+
+    public synchronized TabularData viewConfigFileLoggerLevels() throws IOException
+    {
+        try
+        {
+            LOCK.lock();    
+
+            if (_loggerLevelTabularType == null)
             {
-                _logger.warn("Unable to create logger level list due to :" + e);
+                _logger.warn("TabluarData type not set up correctly");
                 return null;
             }
-        }
 
-        //retrieve the 'logger' element nodes
-        NodeList loggerElements = doc.getElementsByTagName("logger");
-        
-        String loggerName;
-        String level;
+            _logger.info("Getting logger levels from log4j configuration file");
 
-        for (int i = 0; i < loggerElements.getLength(); i++)
-        {
-            Element loggerElement = (Element) loggerElements.item(i);
-            loggerName = loggerElement.getAttribute("name");
+            TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
 
-            //retrieve the logger's mandatory 'level' element's value
-            //It may not be the only child node, so request by tag name.
-            NodeList levelElements = loggerElement.getElementsByTagName("level");
+            Map<String,String> levels = retrieveConfigFileLoggersLevels(_log4jConfigFileName);
 
-            Element levelElement = (Element) levelElements.item(0);
-            level = levelElement.getAttribute("value").toUpperCase();
-            
-            try
+            for (String loggerName : levels.keySet())
             {
-                Object[] itemData = {loggerName, level};
-                CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
-                loggerLevelList.put(loggerData);
-            }
-            catch (OpenDataException e)
-            {
-                _logger.warn("Unable to create logger level list due to :" + e);
-                return null;
+                String level = levels.get(loggerName);
+
+                try
+                {
+                    Object[] itemData = {loggerName, level.toUpperCase()};
+                    CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
+                    loggerLevelList.put(loggerData);
+                }
+                catch (OpenDataException e)
+                {
+                    _logger.warn("Unable to create logger level list due to :" + e);
+                    return null;
+                }
             }
+
+            return loggerLevelList;
+        }
+        finally
+        {
+            LOCK.unlock();
         }
-        
-        return loggerLevelList;
     }
 
     public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException
     {
-        //check that the specified level is a valid log4j Level
         try
         {
-            getLevel(level);
-        }
-        catch (Exception e)
-        {
-            //it isnt a valid level
-            return false;
-        }
-        
-        _logger.info("Setting level to " + level + " for logger '" + logger
-                + "' in log4j xml configuration file: " + _log4jConfigFileName);
-        
-        Document doc = parseConfigFile(_log4jConfigFileName);
+            LOCK.lock();
 
-        //retrieve the 'category' and 'logger' element nodes
-        NodeList categoryElements = doc.getElementsByTagName("category");
-        NodeList loggerElements = doc.getElementsByTagName("logger");
-        
-        //collect them into a single elements list
-        List<Element> logElements = new ArrayList<Element>();
-        
-        for (int i = 0; i < categoryElements.getLength(); i++)
-        {
-            logElements.add((Element) categoryElements.item(i));
-        }
-        for (int i = 0; i < loggerElements.getLength(); i++)
-        {
-            logElements.add((Element) loggerElements.item(i));
-        }
+            //check that the specified level is a valid log4j Level
+            try
+            {
+                getLevel(level);
+            }
+            catch (Exception e)
+            {
+                //it isnt a valid level
+                return false;
+            }
 
-        //try to locate the specified logger/category in the elements retrieved
-        Element logElement = null;
-        for (Element e : logElements)
-        {
-            if (e.getAttribute("name").equals(logger))
+            _logger.info("Setting level to " + level + " for logger '" + logger
+                    + "' in log4j xml configuration file: " + _log4jConfigFileName);
+
+            Document doc = parseConfigFile(_log4jConfigFileName);
+
+            //retrieve the 'category' and 'logger' element nodes
+            NodeList categoryElements = doc.getElementsByTagName("category");
+            NodeList loggerElements = doc.getElementsByTagName("logger");
+
+            //collect them into a single elements list
+            List<Element> logElements = new ArrayList<Element>();
+
+            for (int i = 0; i < categoryElements.getLength(); i++)
             {
-                logElement = e;
-                break;
+                logElements.add((Element) categoryElements.item(i));
+            }
+            for (int i = 0; i < loggerElements.getLength(); i++)
+            {
+                logElements.add((Element) loggerElements.item(i));
             }
-        }
 
-        if (logElement == null)
-        {
-            //no loggers/categories with given name found, does not exist to update
-            _logger.warn("Specified logger does not exist in the configuration file: " +logger);
-            return false;
-        }
+            //try to locate the specified logger/category in the elements retrieved
+            Element logElement = null;
+            for (Element e : logElements)
+            {
+                if (e.getAttribute("name").equals(logger))
+                {
+                    logElement = e;
+                    break;
+                }
+            }
 
-        //retrieve the optional 'priority' or 'level' sub-element value.
-        //It may not be the only child node, so request by tag name.
-        NodeList priorityElements = logElement.getElementsByTagName("priority");
-        NodeList levelElements = logElement.getElementsByTagName("level");
+            if (logElement == null)
+            {
+                //no loggers/categories with given name found, does not exist to update
+                _logger.warn("Specified logger does not exist in the configuration file: " +logger);
+                return false;
+            }
 
-        Element levelElement = null;
-        if (priorityElements.getLength() != 0)
-        {
-            levelElement = (Element) priorityElements.item(0);
-        }
-        else if (levelElements.getLength() != 0)
-        {
-            levelElement = (Element) levelElements.item(0);
+            //retrieve the optional 'priority' or 'level' sub-element value.
+            //It may not be the only child node, so request by tag name.
+            NodeList priorityElements = logElement.getElementsByTagName("priority");
+            NodeList levelElements = logElement.getElementsByTagName("level");
+
+            Element levelElement = null;
+            if (priorityElements.getLength() != 0)
+            {
+                levelElement = (Element) priorityElements.item(0);
+            }
+            else if (levelElements.getLength() != 0)
+            {
+                levelElement = (Element) levelElements.item(0);
+            }
+            else
+            {
+                //there is no exiting priority or level element to update
+                return false;
+            }
+
+            //update the element with the new level/priority
+            levelElement.setAttribute("value", level.toLowerCase());
+
+            //output the new file
+            return writeUpdatedConfigFile(_log4jConfigFileName, doc);
         }
-        else
+        finally
         {
-            //there is no exiting priority or level element to update
-            return false;
+            LOCK.unlock();
         }
-        
-        //update the element with the new level/priority
-        levelElement.setAttribute("value", level);
-        
-        //output the new file
-        return writeUpdatedConfigFile(_log4jConfigFileName, doc);
     }
 
     
@@ -574,102 +654,167 @@
      * and not the only possible child element.
      */
     
-    public synchronized String getConfigFileRootLoggerLevel() throws IOException
+    public static synchronized String retrieveConfigFileRootLoggerLevel(String fileName) throws IOException
     {
-        _logger.info("Getting root logger level from log4j configuration file");
+        try
+        {
+            LOCK.lock();
 
-        Document doc = parseConfigFile(_log4jConfigFileName);
-       
-        //retrieve the optional 'root' element node
-        NodeList rootElements = doc.getElementsByTagName("root");
+            Document doc = parseConfigFile(fileName);
 
-        if (rootElements.getLength() == 0)
-        {
-            //there is not root logger definition
-            return null;
-        }
+            //retrieve the optional 'root' element node
+            NodeList rootElements = doc.getElementsByTagName("root");
 
-        Element rootElement = (Element) rootElements.item(0);
+            if (rootElements.getLength() == 0)
+            {
+                //there is no root logger definition
+                return "N/A";
+            }
 
-        //retrieve the optional 'priority' or 'level' element value.
-        //It may not be the only child node, so request by tag name.
-        NodeList priorityElements = rootElement.getElementsByTagName("priority");
-        NodeList levelElements = rootElement.getElementsByTagName("level");
-        String priority = null;
-        
-        if (priorityElements.getLength() != 0)
-        {
-            Element priorityElement = (Element) priorityElements.item(0);
-            priority = priorityElement.getAttribute("value");
-        }
-        else if(levelElements.getLength() != 0)
-        {
-            Element levelElement = (Element) levelElements.item(0);
-            priority = levelElement.getAttribute("value");
-        }
+            Element rootElement = (Element) rootElements.item(0);
 
-        if(priority != null)
-        {
-            return priority.toUpperCase();
+            //retrieve the optional 'priority' or 'level' element value.
+            //It may not be the only child node, so request by tag name.
+            NodeList priorityElements = rootElement.getElementsByTagName("priority");
+            NodeList levelElements = rootElement.getElementsByTagName("level");
+            String priority = null;
+
+            if (priorityElements.getLength() != 0)
+            {
+                Element priorityElement = (Element) priorityElements.item(0);
+                priority = priorityElement.getAttribute("value");
+            }
+            else if(levelElements.getLength() != 0)
+            {
+                Element levelElement = (Element) levelElements.item(0);
+                priority = levelElement.getAttribute("value");
+            }
+
+            if(priority != null)
+            {
+                return priority;
+            }
+            else
+            {
+                return "N/A";
+            }
         }
-        else
+        finally
         {
-            return null;
+            LOCK.unlock();
         }
     }
     
+    public synchronized String getConfigFileRootLoggerLevel() throws IOException
+    {
+        return retrieveConfigFileRootLoggerLevel(_log4jConfigFileName).toUpperCase();
+    }
+    
     public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException
     {
-        //check that the specified level is a valid log4j Level
         try
         {
-            getLevel(level);
+            LOCK.lock();
+
+            //check that the specified level is a valid log4j Level
+            try
+            {
+                Level newLevel = getLevel(level);
+                if(newLevel == null)
+                {
+                    //A null Level reference implies inheritance. Setting the config file RootLogger 
+                    //to "null" or "inherited" just ensures it defaults to DEBUG at startup as Log4J 
+                    //prevents this catastrophic situation at startup and runtime anyway.
+                    return false;
+                }
+            }
+            catch (Exception e)
+            {
+                //it isnt a valid level
+                return false;
+            }
+
+            _logger.info("Setting level to " + level + " for the Root logger in " +
+                    "log4j xml configuration file: " + _log4jConfigFileName);
+
+            Document doc = parseConfigFile(_log4jConfigFileName);
+
+            //retrieve the optional 'root' element node
+            NodeList rootElements = doc.getElementsByTagName("root");
+
+            if (rootElements.getLength() == 0)
+            {
+                return false;
+            }
+
+            Element rootElement = (Element) rootElements.item(0);
+
+            //retrieve the optional 'priority' or 'level' sub-element value.
+            //It may not be the only child node, so request by tag name.
+            NodeList priorityElements = rootElement.getElementsByTagName("priority");
+            NodeList levelElements = rootElement.getElementsByTagName("level");
+
+            Element levelElement = null;
+            if (priorityElements.getLength() != 0)
+            {
+                levelElement = (Element) priorityElements.item(0);
+            }
+            else if (levelElements.getLength() != 0)
+            {
+                levelElement = (Element) levelElements.item(0);
+            }
+            else
+            {
+                //there is no exiting priority/level to update
+                return false;
+            }
+
+            //update the element with the new level/priority
+            levelElement.setAttribute("value", level);
+
+            //output the new file
+            return writeUpdatedConfigFile(_log4jConfigFileName, doc);
         }
-        catch (Exception e)
+        finally
         {
-            //it isnt a valid level
-            return false;
+            LOCK.unlock();
         }
-        
-        _logger.info("Setting level to " + level + " for the Root logger in " +
-        		"log4j xml configuration file: " + _log4jConfigFileName);
+    }
 
-        Document doc = parseConfigFile(_log4jConfigFileName);
-        
-        //retrieve the optional 'root' element node
-        NodeList rootElements = doc.getElementsByTagName("root");
+    public synchronized void reloadConfigFile() throws IOException
+    {
+        try
+        {
+            LOCK.lock();
 
-        if (rootElements.getLength() == 0)
+            QpidLog4JConfigurator.configure(_log4jConfigFileName);
+            _logger.info("Applied log4j configuration from: " + _log4jConfigFileName);
+        }
+        catch (IllegalLoggerLevelException e)
         {
-            return false;
+            _logger.warn("The log4j configuration reload request was aborted: " + e);
+            //recommended that MBeans should use standard java.* and javax.* exceptions only
+            throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
         }
-
-        Element rootElement = (Element) rootElements.item(0);
-
-        //retrieve the optional 'priority' or 'level' sub-element value.
-        //It may not be the only child node, so request by tag name.
-        NodeList priorityElements = rootElement.getElementsByTagName("priority");
-        NodeList levelElements = rootElement.getElementsByTagName("level");
-
-        Element levelElement = null;
-        if (priorityElements.getLength() != 0)
+        catch (ParserConfigurationException e)
+        {
+            _logger.warn("The log4j configuration reload request was aborted: " + e);
+            throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
+        }
+        catch (SAXException e)
         {
-            levelElement = (Element) priorityElements.item(0);
+            _logger.warn("The log4j configuration reload request was aborted: " + e);
+            //recommended that MBeans should use standard java.* and javax.* exceptions only
+            throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
         }
-        else if (levelElements.getLength() != 0)
+        catch (IOException e)
         {
-            levelElement = (Element) levelElements.item(0);
+            _logger.warn("The log4j configuration reload request was aborted: " + e);
+            throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
         }
-        else
+        finally
         {
-            //there is no exiting priority/level to update
-            return false;
+            LOCK.unlock();
         }
-        
-        //update the element with the new level/priority
-        levelElement.setAttribute("value", level);
-
-        //output the new file
-        return writeUpdatedConfigFile(_log4jConfigFileName, doc);
     }
 }

Propchange: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/management/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  5 12:26:55 2009
@@ -1,3 +1,3 @@
 /qpid/branches/0.5-release/qpid/java/broker/src/main/java/org/apache/qpid/server/management:757268
 /qpid/branches/jmx_mc_gsoc09/qpid/java/broker/src/main/java/org/apache/qpid/server/management:787599
-/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/management:753219-753220,753253,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-804202
+/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/management:753219-753220,753253,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-807984

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java Mon Oct  5 12:26:55 2009
@@ -35,11 +35,7 @@
 import javax.management.MBeanServerFactory;
 import javax.management.ObjectName;
 import javax.management.NotificationListener;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotificationFilter;
 import javax.management.NotificationFilterSupport;
-import javax.management.InstanceNotFoundException;
-import javax.management.relation.MBeanServerNotificationFilter;
 import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXServiceURL;
 import javax.management.remote.MBeanServerForwarder;
@@ -82,6 +78,7 @@
     public static final int PORT_EXPORT_OFFSET = 100;
 
     private final MBeanServer _mbeanServer;
+    private JMXConnectorServer _cs;
     private Registry _rmiRegistry;
     
 
@@ -120,7 +117,6 @@
         Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();        
         PrincipalDatabase db = map.get(jmxDatabaseName);
 
-        final JMXConnectorServer cs;
         HashMap<String,Object> env = new HashMap<String,Object>();
 
         //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
@@ -246,7 +242,7 @@
                 "service:jmx:rmi://"+hostname+":"+(port+PORT_EXPORT_OFFSET)+"/jndi/rmi://"+hostname+":"+port+"/jmxrmi");
 
         final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port+PORT_EXPORT_OFFSET);
-        cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
+        _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
         {   
             @Override  
             public synchronized void start() throws IOException
@@ -282,7 +278,7 @@
 
         //Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
         MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
-        cs.setMBeanServerForwarder(mbsf);
+        _cs.setMBeanServerForwarder(mbsf);
 
         NotificationFilterSupport filter = new NotificationFilterSupport();
         filter.enableType(JMXConnectionNotification.OPENED);
@@ -290,9 +286,9 @@
         filter.enableType(JMXConnectionNotification.FAILED);
         // Get the handler that is used by the above MBInvocationHandler Proxy.
         // which is the MBeanInvocationHandlerImpl and so also a NotificationListener
-        cs.addNotificationListener((NotificationListener) Proxy.getInvocationHandler(mbsf), filter, null);
+        _cs.addNotificationListener((NotificationListener) Proxy.getInvocationHandler(mbsf), filter, null);
 
-        cs.start();
+        _cs.start();
 
 
         CurrentActor.get().message(ManagementConsoleMessages.MNG_1004());
@@ -377,6 +373,19 @@
             UnicastRemoteObject.unexportObject(_rmiRegistry, true);
         }
         
+        if (_cs != null)
+        {
+            // Stopping the JMX ConnectorServer
+            try
+            {
+                _cs.stop();
+            }
+            catch (IOException e)
+            {
+                _log.warn("Error while closing the JMX ConnectorServer: " + e.getMessage());
+            }
+        }
+        
         //ObjectName query to gather all Qpid related MBeans
         ObjectName mbeanNameQuery = null;
         try

Propchange: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Oct  5 12:26:55 2009
@@ -1,3 +1,3 @@
 /qpid/branches/0.5-release/qpid/java/broker/src/main/java/org/apache/qpid/server/queue:757257
 /qpid/branches/jmx_mc_gsoc09/qpid/java/broker/src/main/java/org/apache/qpid/server/queue:787599
-/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue:753219-753220,753253,757270,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-804202
+/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/queue:753219-753220,753253,757270,758730,759097,760919,761721,762365,762992,763959,764026,764109,764140,764790,796196-807984

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java Mon Oct  5 12:26:55 2009
@@ -27,6 +27,7 @@
 import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
 import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.util.FileUtils;
 import org.apache.log4j.Logger;
 import org.apache.commons.configuration.ConfigurationException;
 
@@ -439,16 +440,44 @@
 
             // Create temporary file
             File tmp = File.createTempFile(_accessFile.getName(), ".tmp");
+            tmp.deleteOnExit();
 
             FileOutputStream output = new FileOutputStream(tmp);
             _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser());
             output.close();
 
-            // Rename new file to main file
-            tmp.renameTo(_accessFile);
-
-            // delete tmp
-            tmp.delete();
+            // Swap temp file to main rights file.
+            File old = new File(_accessFile.getAbsoluteFile() + ".old");
+            if (old.exists())
+            {
+                old.delete();
+            }
+            
+            try
+            {
+                if(!_accessFile.renameTo(old))
+                {
+                    FileUtils.copyCheckedEx(_accessFile, old);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Could not backup the existing management rights file: " +e);
+                throw new IOException("Could not backup the existing management rights file: " +e);
+            }
+            
+            try
+            {
+                if(!tmp.renameTo(_accessFile))
+                {
+                    FileUtils.copyCheckedEx(tmp, _accessFile);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.warn("Could not copy the new management rights file into place: " +e);
+                throw new IOException("Could not copy the new management rights file into place" +e);
+            }
         }
         finally
         {

Modified: qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java?rev=821770&r1=821769&r2=821770&view=diff
==============================================================================
--- qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java (original)
+++ qpid/branches/java-broker-0-10/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java Mon Oct  5 12:26:55 2009
@@ -25,6 +25,7 @@
 import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
 import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.qpid.util.FileUtils;
 
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.login.AccountNotFoundException;
@@ -428,6 +429,7 @@
             BufferedReader reader = null;
             PrintStream writer = null;
             File tmp = File.createTempFile(_passwordFile.getName(), ".tmp");
+            tmp.deleteOnExit();
 
             try
             {
@@ -501,6 +503,11 @@
                     }
                 }
             }
+            catch(IOException e)
+            {
+                _logger.error("Unable to create the new password file: " + e);
+                throw new IOException("Unable to create the new password file" + e);
+            }
             finally
             {
                 if (reader != null)
@@ -512,16 +519,39 @@
                 {
                     writer.close();
                 }
-
-                // Swap temp file to main password file.
-                File old = new File(_passwordFile.getAbsoluteFile() + ".old");
-                if (old.exists())
-                {
-                    old.delete();
-                }
-                _passwordFile.renameTo(old);
-                tmp.renameTo(_passwordFile);
-                tmp.delete();
+            }
+            
+            // Swap temp file to main password file.
+            File old = new File(_passwordFile.getAbsoluteFile() + ".old");
+            if (old.exists())
+            {
+                old.delete();
+            }
+            
+            try
+            {
+                if(!_passwordFile.renameTo(old))
+                {
+                    FileUtils.copyCheckedEx(_passwordFile, old);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.error("Could not backup the existing password file: " +e);
+                throw new IOException("Could not backup the existing password file: " + e);
+            }
+            
+            try
+            {
+                if(!tmp.renameTo(_passwordFile))
+                {
+                    FileUtils.copyCheckedEx(tmp, _passwordFile);
+                }
+            }
+            catch (IOException e)
+            {
+                _logger.error("Could not copy the new password file into place: " +e);
+                throw new IOException("Could not copy the new password file into place: " + e);
             }
         }
         finally



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org