qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject svn commit: r1433054 - in /qpid/trunk/qpid/cpp/src: qpid/management/ManagementAgent.cpp qpid/management/ManagementAgent.h tests/BrokerMgmtAgent.cpp
Date Mon, 14 Jan 2013 19:08:45 GMT
Author: aconway
Date: Mon Jan 14 19:08:45 2013
New Revision: 1433054

URL: http://svn.apache.org/viewvc?rev=1433054&view=rev
Log:
QPID-4514: Clean up cluster code: Obsolete management import/export functions.

Remove management fucntions used to import/export data from the cluster module.

Modified:
    qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp
    qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.h
    qpid/trunk/qpid/cpp/src/tests/BrokerMgmtAgent.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp?rev=1433054&r1=1433053&r2=1433054&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.cpp Mon Jan 14 19:08:45 2013
@@ -2551,70 +2551,6 @@ void ManagementAgent::SchemaClass::mapDe
     }
 }
 
-void ManagementAgent::exportSchemas(string& out) {
-    Variant::List list_;
-    Variant::Map map_, kmap, cmap;
-
-    for (PackageMap::const_iterator i = packages.begin(); i != packages.end(); ++i) {
-        string name = i->first;
-        const ClassMap& classes = i ->second;
-        for (ClassMap::const_iterator j = classes.begin(); j != classes.end(); ++j) {
-            const SchemaClassKey& key = j->first;
-            const SchemaClass& klass = j->second;
-            if (klass.writeSchemaCall == 0) { // Ignore built-in schemas.
-                // Encode name, schema-key, schema-class
-
-                map_.clear();
-                kmap.clear();
-                cmap.clear();
-
-                key.mapEncode(kmap);
-                klass.mapEncode(cmap);
-
-                map_["_pname"] = name;
-                map_["_key"] = kmap;
-                map_["_class"] = cmap;
-                list_.push_back(map_);
-            }
-        }
-    }
-
-    ListCodec::encode(list_, out);
-}
-
-void ManagementAgent::importSchemas(qpid::framing::Buffer& inBuf) {
-
-    string buf(inBuf.getPointer(), inBuf.available());
-    Variant::List content;
-    ListCodec::decode(buf, content);
-    Variant::List::const_iterator l;
-
-
-    for (l = content.begin(); l != content.end(); l++) {
-        string package;
-        SchemaClassKey key;
-        SchemaClass klass;
-        Variant::Map map_, kmap, cmap;
-        Variant::Map::const_iterator i;
-        
-        map_ = l->asMap();
-
-        if ((i = map_.find("_pname")) != map_.end()) {
-            package = i->second.asString();
-
-            if ((i = map_.find("_key")) != map_.end()) {
-                key.mapDecode(i->second.asMap());
-
-                if ((i = map_.find("_class")) != map_.end()) {
-                    klass.mapDecode(i->second.asMap());
-
-                    packages[package][key] = klass;
-                }
-            }
-        }
-    }
-}
-
 void ManagementAgent::RemoteAgent::mapEncode(Variant::Map& map_) const {
     Variant::Map _objId, _values;
 
@@ -2658,52 +2594,6 @@ void ManagementAgent::RemoteAgent::mapDe
     mgmtObject->set_connectionRef(connectionRef);
 }
 
-void ManagementAgent::exportAgents(string& out) {
-    Variant::List list_;
-    Variant::Map map_, omap, amap;
-
-    for (RemoteAgentMap::const_iterator i = remoteAgents.begin();
-         i != remoteAgents.end();
-         ++i)
-    {
-        // TODO aconway 2010-03-04: see comment in ManagementAgent::RemoteAgent::encode
-        boost::shared_ptr<RemoteAgent> agent(i->second);
-
-        map_.clear();
-        amap.clear();
-
-        agent->mapEncode(amap);
-        map_["_remote_agent"] = amap;
-        list_.push_back(map_);
-    }
-
-    ListCodec::encode(list_, out);
-}
-
-void ManagementAgent::importAgents(qpid::framing::Buffer& inBuf) {
-    string buf(inBuf.getPointer(), inBuf.available());
-    Variant::List content;
-    ListCodec::decode(buf, content);
-    Variant::List::const_iterator l;
-    sys::Mutex::ScopedLock lock(userLock);
-
-    for (l = content.begin(); l != content.end(); l++) {
-        boost::shared_ptr<RemoteAgent> agent(new RemoteAgent(*this));
-        Variant::Map map_;
-        Variant::Map::const_iterator i;
-
-        map_ = l->asMap();
-
-        if ((i = map_.find("_remote_agent")) != map_.end()) {
-
-            agent->mapDecode(i->second.asMap());
-
-            addObject (agent->mgmtObject, 0, false);
-            remoteAgents[agent->connectionRef] = agent;
-        }
-    }
-}
-
 namespace {
 bool isDeletedMap(const ManagementObjectMap::value_type& value) {
     return value.second->isDeleted();
@@ -2782,54 +2672,6 @@ Variant::Map ManagementAgent::toMap(cons
     return map;
 }
 
-
-// Build up a list of the current set of deleted objects that are pending their
-// next (last) publish-ment.
-void ManagementAgent::exportDeletedObjects(DeletedObjectList& outList)
-{
-    outList.clear();
-
-    sys::Mutex::ScopedLock lock (userLock);
-
-    moveNewObjects();
-    moveDeletedObjects();
-
-    // now copy the pending deletes into the outList
-    for (PendingDeletedObjsMap::iterator mIter = pendingDeletedObjs.begin();
-         mIter != pendingDeletedObjs.end(); mIter++) {
-        for (DeletedObjectList::iterator lIter = mIter->second.begin();
-             lIter != mIter->second.end(); lIter++) {
-            outList.push_back(*lIter);
-        }
-    }
-}
-
-// Called by cluster to reset the management agent's list of deleted
-// objects to match the rest of the cluster.
-void ManagementAgent::importDeletedObjects(const DeletedObjectList& inList)
-{
-    sys::Mutex::ScopedLock lock (userLock);
-    sys::Mutex::ScopedLock objLock(objectLock);
-    // Clear out any existing deleted objects
-    moveNewObjects();
-    pendingDeletedObjs.clear();
-    ManagementObjectMap::iterator i = managementObjects.begin();
-    // Silently drop any deleted objects left over from receiving the update.
-    while (i != managementObjects.end()) {
-        ManagementObject::shared_ptr object = i->second;
-        if (object->isDeleted()) {
-            managementObjects.erase(i++);
-        }
-        else ++i;
-    }
-    for (DeletedObjectList::const_iterator lIter = inList.begin(); lIter != inList.end();
lIter++) {
-
-        std::string classkey((*lIter)->packageName + std::string(":") + (*lIter)->className);
-        pendingDeletedObjs[classkey].push_back(*lIter);
-    }
-}
-
-
 // construct a DeletedObject from a management object.
 ManagementAgent::DeletedObject::DeletedObject(ManagementObject::shared_ptr src, bool v1,
bool v2)
     : packageName(src->getPackageName()),
@@ -2867,26 +2709,6 @@ ManagementAgent::DeletedObject::DeletedO
     }
 }
 
-
-
-// construct a DeletedObject from an encoded representation. Used by
-// clustering to move deleted objects between clustered brokers.  See
-// DeletedObject::encode() for the reverse.
-ManagementAgent::DeletedObject::DeletedObject(const std::string& encoded)
-{
-    qpid::types::Variant::Map map_;
-    MapCodec::decode(encoded, map_);
-
-    packageName = map_["_package_name"].getString();
-    className = map_["_class_name"].getString();
-    objectId = map_["_object_id"].getString();
-
-    encodedV1Config = map_["_v1_config"].getString();
-    encodedV1Inst = map_["_v1_inst"].getString();
-    encodedV2 = map_["_v2_data"].asMap();
-}
-
-
 // Remove Deleted objects, and save for later publishing...
 bool ManagementAgent::moveDeletedObjects() {
     typedef vector<pair<ObjectId, ManagementObject::shared_ptr> > DeleteList;

Modified: qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.h?rev=1433054&r1=1433053&r2=1433054&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/management/ManagementAgent.h Mon Jan 14 19:08:45 2013
@@ -118,18 +118,6 @@ public:
     /** Disallow a method. Attempts to call it will receive an exception with message. */
     void disallow(const std::string& className, const std::string& methodName, const
std::string& message);
 
-    /** Serialize my schemas as a binary blob into schemaOut */
-    void exportSchemas(std::string& schemaOut);
-
-    /** Serialize my remote-agent map as a binary blob into agentsOut */
-    void exportAgents(std::string& agentsOut);
-
-    /** Decode a serialized schemas and add to my schema cache */
-    void importSchemas(framing::Buffer& inBuf);
-
-    /** Decode a serialized agent map */
-    void importAgents(framing::Buffer& inBuf);
-
     uint16_t getBootSequence(void) { return bootSequence; }
     void setBootSequence(uint16_t b) { bootSequence = b; writeData(); }
 
@@ -138,20 +126,11 @@ public:
 
     static types::Variant::Map toMap(const framing::FieldTable& from);
 
-    // For Clustering: management objects that have been marked as
-    // "deleted", but are waiting for their last published object
-    // update are not visible to the cluster replication code.  These
-    // interfaces allow clustering to gather up all the management
-    // objects that are deleted in order to allow all clustered
-    // brokers to publish the same set of deleted objects.
-
     class DeletedObject {
       public:
         typedef boost::shared_ptr<DeletedObject> shared_ptr;
         DeletedObject(ManagementObject::shared_ptr, bool v1, bool v2);
-        DeletedObject( const std::string &encoded );
         ~DeletedObject() {};
-        void encode( std::string& toBuffer );
         const std::string getKey() const {
             // used to batch up objects of the same class type
             return std::string(packageName + std::string(":") + className);
@@ -171,12 +150,6 @@ public:
 
     typedef std::vector<DeletedObject::shared_ptr> DeletedObjectList;
 
-    /** returns a snapshot of all currently deleted management objects. */
-    void exportDeletedObjects( DeletedObjectList& outList );
-
-    /** Import a list of deleted objects to send on next publish interval. */
-    void importDeletedObjects( const DeletedObjectList& inList );
-
 private:
     //  Storage for tracking remote management agents, attached via the client
     //  management agent API.

Modified: qpid/trunk/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/BrokerMgmtAgent.cpp?rev=1433054&r1=1433053&r2=1433054&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/BrokerMgmtAgent.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/BrokerMgmtAgent.cpp Mon Jan 14 19:08:45 2013
@@ -324,361 +324,6 @@ QPID_AUTO_TEST_CASE(v2ObjPublish)
     delete tm;
 }
 
-
-// verify that a deleted object is exported correctly using the
-// exportDeletedObjects() method.  V1 testcase.
-//
-QPID_AUTO_TEST_CASE(v1ExportDelObj)
-{
-    AgentFixture* fix = new AgentFixture(3);
-    management::ManagementAgent* agent;
-    agent = fix->getBrokerAgent();
-
-    // create a manageable test object
-    TestManageable *tm = new TestManageable(agent, std::string("myObj"));
-    uint32_t objLen = tm->GetManagementObject()->writePropertiesSize();
-
-    Receiver r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-
-    agent->addObject(tm->GetManagementObject(), 1);
-
-    // wait for the object to be published
-    Message m1;
-    BOOST_CHECK(r1.fetch(m1, Duration::SECOND * 6));
-
-    TestObjectVector objs;
-    decodeV1ObjectUpdates(m1, objs, objLen);
-    BOOST_CHECK(objs.size() > 0);
-
-    // destroy the object, then immediately export (before the next poll cycle)
-
-    ::qpid::management::ManagementAgent::DeletedObjectList delObjs;
-    tm->GetManagementObject()->resourceDestroy();
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 1);
-
-    // wait for the deleted object to be published
-
-    bool isDeleted = false;
-    while (!isDeleted && r1.fetch(m1, Duration::SECOND * 6)) {
-
-        decodeV1ObjectUpdates(m1, objs, objLen);
-        BOOST_CHECK(objs.size() > 0);
-
-        for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++)
{
-
-            TestManageable::validateTestObjectProperties(**oIter);
-
-            qpid::types::Variant::Map mappy;
-            (*oIter)->writeTimestamps(mappy);
-            if (mappy["_delete_ts"].asUint64() != 0)
-                isDeleted = true;
-        }
-    }
-
-    BOOST_CHECK(isDeleted);
-
-    // verify there are no deleted objects to export now.
-
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 0);
-
-    r1.close();
-    delete fix;
-    delete tm;
-}
-
-
-// verify that a deleted object is imported correctly using the
-// importDeletedObjects() method.  V1 testcase.
-//
-QPID_AUTO_TEST_CASE(v1ImportDelObj)
-{
-    AgentFixture* fix = new AgentFixture(3);
-    management::ManagementAgent* agent;
-    agent = fix->getBrokerAgent();
-
-    // create a manageable test object
-    TestManageable *tm = new TestManageable(agent, std::string("anObj"));
-    uint32_t objLen = tm->GetManagementObject()->writePropertiesSize();
-
-    Receiver r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-
-    agent->addObject(tm->GetManagementObject(), 1);
-
-    // wait for the object to be published
-    Message m1;
-    BOOST_CHECK(r1.fetch(m1, Duration::SECOND * 6));
-
-    TestObjectVector objs;
-    decodeV1ObjectUpdates(m1, objs, objLen);
-    BOOST_CHECK(objs.size() > 0);
-
-    // destroy the object, then immediately export (before the next poll cycle)
-
-    ::qpid::management::ManagementAgent::DeletedObjectList delObjs;
-    tm->GetManagementObject()->resourceDestroy();
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 1);
-
-    // destroy the broker, and reinistantiate a new one without populating it
-    // with a TestObject.
-
-    r1.close();
-    delete fix;
-    delete tm;    // should no longer be necessary
-
-    fix = new AgentFixture(3);
-    r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-    agent = fix->getBrokerAgent();
-    agent->importDeletedObjects( delObjs );
-
-    // wait for the deleted object to be published
-
-    bool isDeleted = false;
-    while (!isDeleted && r1.fetch(m1, Duration::SECOND * 6)) {
-
-        decodeV1ObjectUpdates(m1, objs, objLen);
-        BOOST_CHECK(objs.size() > 0);
-
-        for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++)
{
-
-            TestManageable::validateTestObjectProperties(**oIter);
-
-            qpid::types::Variant::Map mappy;
-            (*oIter)->writeTimestamps(mappy);
-            if (mappy["_delete_ts"].asUint64() != 0)
-                isDeleted = true;
-        }
-    }
-
-    BOOST_CHECK(isDeleted);
-
-    // verify there are no deleted objects to export now.
-
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 0);
-
-    r1.close();
-    delete fix;
-}
-
-
-// verify that an object that is added and deleted prior to the
-// first poll cycle is accounted for by the export
-//
-QPID_AUTO_TEST_CASE(v1ExportFastDelObj)
-{
-    AgentFixture* fix = new AgentFixture(3);
-    management::ManagementAgent* agent;
-    agent = fix->getBrokerAgent();
-
-    // create a manageable test object
-    TestManageable *tm = new TestManageable(agent, std::string("objectifyMe"));
-
-    // add, then immediately delete and export the object...
-
-    ::qpid::management::ManagementAgent::DeletedObjectList delObjs;
-    agent->addObject(tm->GetManagementObject(), 999);
-    tm->GetManagementObject()->resourceDestroy();
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 1);
-
-    delete fix;
-    delete tm;
-}
-
-
-// Verify that we can export and import multiple deleted objects correctly.
-//
-QPID_AUTO_TEST_CASE(v1ImportMultiDelObj)
-{
-    AgentFixture* fix = new AgentFixture(3);
-    management::ManagementAgent* agent;
-    agent = fix->getBrokerAgent();
-
-    Receiver r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-
-    // populate the agent with multiple test objects
-    const size_t objCount = 50;
-    std::vector<TestManageable *> tmv;
-    uint32_t objLen;
-
-    for (size_t i = 0; i < objCount; i++) {
-        std::stringstream key;
-        key << "testobj-" << std::setfill('x') << std::setw(4) <<
i;
-        // (no, seriously, I didn't just do that.)
-        // Note well: we have to keep the key string length EXACTLY THE SAME
-        // FOR ALL OBJECTS, so objLen will be the same.  Otherwise the
-        // decodeV1ObjectUpdates() will fail (v1 lacks explict encoded length).
-        TestManageable *tm = new TestManageable(agent, key.str());
-        objLen = tm->GetManagementObject()->writePropertiesSize();
-        agent->addObject(tm->GetManagementObject(), i + 1);
-        tmv.push_back(tm);
-    }
-
-    // wait for the objects to be published
-    Message m1;
-    uint32_t    msgCount = 0;
-    while(r1.fetch(m1, Duration::SECOND * 6)) {
-        TestObjectVector objs;
-        decodeV1ObjectUpdates(m1, objs, objLen);
-        msgCount += objs.size();
-    }
-
-    BOOST_CHECK_EQUAL(msgCount, objCount);
-
-    // destroy some of the objects, then immediately export (before the next poll cycle)
-
-    uint32_t delCount = 0;
-    for (size_t i = 0; i < objCount; i += 2) {
-        tmv[i]->GetManagementObject()->resourceDestroy();
-        delCount++;
-    }
-
-    ::qpid::management::ManagementAgent::DeletedObjectList delObjs;
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK_EQUAL(delObjs.size(), delCount);
-
-    // destroy the broker, and reinistantiate a new one without populating it
-    // with TestObjects.
-
-    r1.close();
-    delete fix;
-    while (tmv.size()) {
-        delete tmv.back();
-        tmv.pop_back();
-    }
-
-    fix = new AgentFixture(3);
-    r1 = fix->createV1DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-    agent = fix->getBrokerAgent();
-    agent->importDeletedObjects( delObjs );
-
-    // wait for the deleted object to be published, verify the count
-
-    uint32_t countDels = 0;
-    while (r1.fetch(m1, Duration::SECOND * 6)) {
-        TestObjectVector objs;
-        decodeV1ObjectUpdates(m1, objs, objLen);
-        BOOST_CHECK(objs.size() > 0);
-
-                
-        for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++)
{
-
-            TestManageable::validateTestObjectProperties(**oIter);
-
-            qpid::types::Variant::Map mappy;
-            (*oIter)->writeTimestamps(mappy);
-            if (mappy["_delete_ts"].asUint64() != 0)
-                countDels++;
-        }
-    }
-
-    // make sure we get the correct # of deleted objects
-    BOOST_CHECK_EQUAL(countDels, delCount);
-
-    // verify there are no deleted objects to export now.
-
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 0);
-
-    r1.close();
-    delete fix;
-}
-
-// Verify that we can export and import multiple deleted objects correctly.
-// QMF V2 variant
-QPID_AUTO_TEST_CASE(v2ImportMultiDelObj)
-{
-    AgentFixture* fix = new AgentFixture(3, true);
-    management::ManagementAgent* agent;
-    agent = fix->getBrokerAgent();
-
-    Receiver r1 = fix->createV2DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-
-    // populate the agent with multiple test objects
-    const size_t objCount = 50;
-    std::vector<TestManageable *> tmv;
-
-    for (size_t i = 0; i < objCount; i++) {
-        std::stringstream key;
-        key << "testobj-" << i;
-        TestManageable *tm = new TestManageable(agent, key.str());
-        if (tm->GetManagementObject()->writePropertiesSize()) {}
-        agent->addObject(tm->GetManagementObject(), key.str());
-        tmv.push_back(tm);
-    }
-
-    // wait for the objects to be published
-    Message m1;
-    uint32_t    msgCount = 0;
-    while(r1.fetch(m1, Duration::SECOND * 6)) {
-        TestObjectVector objs;
-        decodeV2ObjectUpdates(m1, objs);
-        msgCount += objs.size();
-    }
-
-    BOOST_CHECK_EQUAL(msgCount, objCount);
-
-    // destroy some of the objects, then immediately export (before the next poll cycle)
-
-    uint32_t delCount = 0;
-    for (size_t i = 0; i < objCount; i += 2) {
-        tmv[i]->GetManagementObject()->resourceDestroy();
-        delCount++;
-    }
-
-    ::qpid::management::ManagementAgent::DeletedObjectList delObjs;
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK_EQUAL(delObjs.size(), delCount);
-
-    // destroy the broker, and reinistantiate a new one without populating it
-    // with TestObjects.
-
-    r1.close();
-    delete fix;
-    while (tmv.size()) {
-        delete tmv.back();
-        tmv.pop_back();
-    }
-
-    fix = new AgentFixture(3, true);
-    r1 = fix->createV2DataIndRcvr("org.apache.qpid.broker.mgmt.test", "#");
-    agent = fix->getBrokerAgent();
-    agent->importDeletedObjects( delObjs );
-
-    // wait for the deleted object to be published, verify the count
-
-    uint32_t countDels = 0;
-    while (r1.fetch(m1, Duration::SECOND * 6)) {
-        TestObjectVector objs;
-        decodeV2ObjectUpdates(m1, objs);
-        BOOST_CHECK(objs.size() > 0);
-
-        for (TestObjectVector::iterator oIter = objs.begin(); oIter != objs.end(); oIter++)
{
-
-            TestManageable::validateTestObjectProperties(**oIter);
-
-            qpid::types::Variant::Map mappy;
-            (*oIter)->writeTimestamps(mappy);
-            if (mappy["_delete_ts"].asUint64() != 0)
-                countDels++;
-        }
-    }
-
-    // make sure we get the correct # of deleted objects
-    BOOST_CHECK_EQUAL(countDels, delCount);
-
-    // verify there are no deleted objects to export now.
-
-    agent->exportDeletedObjects( delObjs );
-    BOOST_CHECK(delObjs.size() == 0);
-
-    r1.close();
-    delete fix;
-}
-
 // See QPID-2997
 QPID_AUTO_TEST_CASE(v2RapidRestoreObj)
 {



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message