diff options
Diffstat (limited to 'qpid/cpp/src/qpid/management/ManagementObject.cpp')
-rw-r--r-- | qpid/cpp/src/qpid/management/ManagementObject.cpp | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/management/ManagementObject.cpp b/qpid/cpp/src/qpid/management/ManagementObject.cpp new file mode 100644 index 0000000000..b4d469afbe --- /dev/null +++ b/qpid/cpp/src/qpid/management/ManagementObject.cpp @@ -0,0 +1,385 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/management/Manageable.h" +#include "qpid/management/ManagementObject.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Buffer.h" +#include "qpid/sys/Time.h" +#include "qpid/sys/Thread.h" +#include "qpid/log/Statement.h" +#include <boost/lexical_cast.hpp> + +#include <stdlib.h> + +using namespace std; +using namespace qpid; +using namespace qpid::management; + +void AgentAttachment::setBanks(uint32_t broker, uint32_t bank) +{ + first = + ((uint64_t) (broker & 0x000fffff)) << 28 | + ((uint64_t) (bank & 0x0fffffff)); +} + +// Deprecated +ObjectId::ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint64_t object) + : agent(0), agentEpoch(seq) +{ + first = + ((uint64_t) (flags & 0x0f)) << 60 | + ((uint64_t) (seq & 0x0fff)) << 48 | + ((uint64_t) (broker & 0x000fffff)) << 28; + second = object; +} + + +ObjectId::ObjectId(uint8_t flags, uint16_t seq, uint32_t broker) + : agent(0), second(0), agentEpoch(seq) +{ + first = + ((uint64_t) (flags & 0x0f)) << 60 | + ((uint64_t) (seq & 0x0fff)) << 48 | + ((uint64_t) (broker & 0x000fffff)) << 28; +} + +ObjectId::ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq) + : agent(_agent), second(0), agentEpoch(seq) +{ + + first = + ((uint64_t) (flags & 0x0f)) << 60 | + ((uint64_t) (seq & 0x0fff)) << 48; +} + + +ObjectId::ObjectId(istream& in) : agent(0) +{ + string text; + in >> text; + fromString(text); +} + +ObjectId::ObjectId(const string& text) : agent(0) +{ + fromString(text); +} + +void ObjectId::fromString(const string& text) +{ +#define FIELDS 5 +#if defined (_WIN32) && !defined (atoll) +# define atoll(X) _atoi64(X) +#endif + + // format: + // V1: <flags>-<sequence>-<broker-bank>-<agent-bank>-<uint64-app-id> + // V2: Not used + + string copy(text.c_str()); + char* cText; + char* field[FIELDS]; + bool atFieldStart = true; + int idx = 0; + + cText = const_cast<char*>(copy.c_str()); + for (char* cursor = cText; *cursor; cursor++) { + if (atFieldStart) { + if (idx >= FIELDS) + throw Exception("Invalid ObjectId format"); + field[idx++] = cursor; + atFieldStart = false; + } else { + if (*cursor == '-') { + *cursor = '\0'; + atFieldStart = true; + } + } + } + + if (idx != FIELDS) + throw Exception("Invalid ObjectId format"); + + agentEpoch = atoll(field[1]); + + first = (atoll(field[0]) << 60) + + (atoll(field[1]) << 48) + + (atoll(field[2]) << 28); + + agentName = string(field[3]); + second = atoll(field[4]); +} + + +bool ObjectId::operator==(const ObjectId &other) const +{ + return v2Key == other.v2Key; +} + +bool ObjectId::operator<(const ObjectId &other) const +{ + return v2Key < other.v2Key; +} + +bool ObjectId::equalV1(const ObjectId &other) const +{ + uint64_t otherFirst = agent == 0 ? other.first : other.first & 0xffff000000000000LL; + return first == otherFirst && second == other.second; +} + +// encode as V1-format binary +void ObjectId::encode(string& buffer) const +{ + const uint32_t len = 16; + char _data[len]; + qpid::framing::Buffer body(_data, len); + + if (agent == 0) + body.putLongLong(first); + else + body.putLongLong(first | agent->first); + body.putLongLong(second); + + body.reset(); + body.getRawData(buffer, len); +} + +// decode as V1-format binary +void ObjectId::decode(const string& buffer) +{ + const uint32_t len = 16; + char _data[len]; + qpid::framing::Buffer body(_data, len); + + body.checkAvailable(buffer.length()); + body.putRawData(buffer); + body.reset(); + first = body.getLongLong(); + second = body.getLongLong(); + v2Key = boost::lexical_cast<string>(second); +} + +// generate the V2 key from the index fields defined +// in the schema. +void ObjectId::setV2Key(const ManagementObject& object) +{ + stringstream oname; + oname << object.getPackageName() << ":" << object.getClassName() << ":" << object.getKey(); + v2Key = oname.str(); +} + + +// encode as V2-format map +void ObjectId::mapEncode(types::Variant::Map& map) const +{ + map["_object_name"] = v2Key; + if (!agentName.empty()) + map["_agent_name"] = agentName; + if (agentEpoch) + map["_agent_epoch"] = agentEpoch; +} + +// decode as v2-format map +void ObjectId::mapDecode(const types::Variant::Map& map) +{ + types::Variant::Map::const_iterator i; + + if ((i = map.find("_object_name")) != map.end()) + v2Key = i->second.asString(); + else + throw Exception("Required _object_name field missing."); + + if ((i = map.find("_agent_name")) != map.end()) + agentName = i->second.asString(); + + if ((i = map.find("_agent_epoch")) != map.end()) + agentEpoch = i->second.asInt64(); +} + + +ObjectId::operator types::Variant::Map() const +{ + types::Variant::Map m; + mapEncode(m); + return m; +} + + + +namespace qpid { +namespace management { + +ostream& operator<<(ostream& out, const ObjectId& i) +{ + uint64_t virtFirst = i.first; + if (i.agent) + virtFirst |= i.agent->getFirst(); + + out << ((virtFirst & 0xF000000000000000LL) >> 60) << + "-" << ((virtFirst & 0x0FFF000000000000LL) >> 48) << + "-" << ((virtFirst & 0x0000FFFFF0000000LL) >> 28) << + "-" << i.agentName << + "-" << i.second << + "(" << i.v2Key << ")"; + return out; +} + +}} + +ManagementObject::ManagementObject(Manageable* _core) : +createTime(qpid::sys::Duration(sys::EPOCH, sys::now())), + destroyTime(0), updateTime(createTime), configChanged(true), + instChanged(true), deleted(false), + coreObject(_core), flags(0), forcePublish(false) {} + +void ManagementObject::setUpdateTime() +{ + updateTime = sys::Duration(sys::EPOCH, sys::now()); +} + +void ManagementObject::resourceDestroy() +{ + QPID_LOG(trace, "Management object marked deleted: " << getObjectId().getV2Key()); + destroyTime = sys::Duration(sys::EPOCH, sys::now()); + deleted = true; +} + +int ManagementObject::maxThreads = 1; +int ManagementObject::nextThreadIndex = 0; + +void ManagementObject::writeTimestamps (string& buf) const +{ + char _data[4000]; + qpid::framing::Buffer body(_data, 4000); + + body.putShortString (getPackageName ()); + body.putShortString (getClassName ()); + body.putBin128 (getMd5Sum ()); + body.putLongLong (updateTime); + body.putLongLong (createTime); + body.putLongLong (destroyTime); + + uint32_t len = body.getPosition(); + body.reset(); + body.getRawData(buf, len); + + string oid; + objectId.encode(oid); + buf += oid; +} + +void ManagementObject::readTimestamps (const string& buf) +{ + char _data[4000]; + qpid::framing::Buffer body(_data, 4000); + string unused; + uint8_t unusedUuid[16]; + + body.checkAvailable(buf.length()); + body.putRawData(buf); + body.reset(); + + body.getShortString(unused); + body.getShortString(unused); + body.getBin128(unusedUuid); + updateTime = body.getLongLong(); + createTime = body.getLongLong(); + destroyTime = body.getLongLong(); +} + +uint32_t ManagementObject::writeTimestampsSize() const +{ + return 1 + getPackageName().length() + // str8 + 1 + getClassName().length() + // str8 + 16 + // bin128 + 8 + // uint64 + 8 + // uint64 + 8 + // uint64 + objectId.encodedSize(); // objectId +} + + +void ManagementObject::writeTimestamps (types::Variant::Map& map) const +{ + // types::Variant::Map oid, sid; + + // sid["_package_name"] = getPackageName(); + // sid["_class_name"] = getClassName(); + // sid["_hash"] = qpid::types::Uuid(getMd5Sum()); + // map["_schema_id"] = sid; + + // objectId.mapEncode(oid); + // map["_object_id"] = oid; + + map["_update_ts"] = updateTime; + map["_create_ts"] = createTime; + map["_delete_ts"] = destroyTime; +} + +void ManagementObject::readTimestamps (const types::Variant::Map& map) +{ + types::Variant::Map::const_iterator i; + + if ((i = map.find("_update_ts")) != map.end()) + updateTime = i->second.asUint64(); + if ((i = map.find("_create_ts")) != map.end()) + createTime = i->second.asUint64(); + if ((i = map.find("_delete_ts")) != map.end()) + destroyTime = i->second.asUint64(); +} + + +void ManagementObject::setReference(ObjectId) {} + +int ManagementObject::getThreadIndex() { + static QPID_TSS int thisIndex = -1; + if (thisIndex == -1) { + Mutex::ScopedLock mutex(accessLock); + thisIndex = nextThreadIndex; + if (nextThreadIndex < maxThreads - 1) + nextThreadIndex++; + } + return thisIndex; +} + + +// void ManagementObject::mapEncode(types::Variant::Map& map, +// bool includeProperties, +// bool includeStatistics) +// { +// types::Variant::Map values; + +// writeTimestamps(map); + +// mapEncodeValues(values, includeProperties, includeStatistics); +// map["_values"] = values; +// } + +// void ManagementObject::mapDecode(const types::Variant::Map& map) +// { +// types::Variant::Map::const_iterator i; + +// readTimestamps(map); + +// if ((i = map.find("_values")) != map.end()) +// mapDecodeValues(i->second.asMap()); +// } |