Skip to content

Commit

Permalink
Added asset removal functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
Will Sobel committed Apr 21, 2014
1 parent 170f77c commit 0e6613a
Show file tree
Hide file tree
Showing 23 changed files with 486 additions and 67 deletions.
2 changes: 1 addition & 1 deletion agent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set (AGENT_VERSION_MAJOR 1)
set (AGENT_VERSION_MINOR 3)
set (AGENT_VERSION_PATCH 0)
set (AGENT_VERSION_BUILD 0)
set (AGENT_VERSION_RC "_RC9")
set (AGENT_VERSION_RC "_RC10")

if(WIN32)
if(CMAKE_CL_64)
Expand Down
7 changes: 6 additions & 1 deletion agent/adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,12 @@ void Adapter::processData(const string& data)
mAgent->updateAsset(device, assetId, list, time);
return;
}

else if (key == "@REMOVE_ASSET@")
{
string assetId = value;
mAgent->removeAsset(device, assetId, time);
return;
}

DataItem *dataItem;
if (device != NULL) {
Expand Down
129 changes: 94 additions & 35 deletions agent/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Agent::Agent(const string& configXmlPath, int aBufferSize, int aMaxAssets, int a
ss >> major >> c >> minor;
if ((*device)->getAssetChanged() == NULL && (major >= 1 || (major == 1 && minor >= 2)))
{
// Create availability data item and add it to the device.
// Create asset change data item and add it to the device.
std::map<string,string> attrs;
attrs["type"] = "ASSET_CHANGED";
attrs["id"] = (*device)->getId() + "_asset_chg";
Expand All @@ -144,7 +144,21 @@ Agent::Agent(const string& configXmlPath, int aBufferSize, int aMaxAssets, int a
(*device)->addDataItem(*di);
(*device)->addDeviceDataItem(*di);
}
}

if ((*device)->getAssetRemoved() == NULL && (major >= 1 || (major == 1 && minor >= 3)))
{
// Create asset removed data item and add it to the device.
std::map<string,string> attrs;
attrs["type"] = "ASSET_REMOVED";
attrs["id"] = (*device)->getId() + "_asset_rem";
attrs["category"] = "EVENT";

DataItem *di = new DataItem(attrs);
di->setComponent(*(*device));
(*device)->addDataItem(*di);
(*device)->addDeviceDataItem(*di);
}
}

// Reload the document for path resolution
mXmlParser->loadDocument(XmlPrinter::printProbe(mInstanceId, mSlidingBufferSize,
Expand Down Expand Up @@ -455,8 +469,7 @@ unsigned int Agent::addToBuffer(DataItem *dataItem,
}

bool Agent::addAsset(Device *aDevice, const string &aId, const string &aAsset,
const string &aType,
const string &aTime)
const string &aType, const string &aTime)
{
// Check to make sure the values are present
if (aType.empty() || aAsset.empty() || aId.empty()) {
Expand All @@ -470,54 +483,66 @@ bool Agent::addAsset(Device *aDevice, const string &aId, const string &aAsset,
else
time = aTime;

AssetPtr ptr;

// Lock the asset addition to protect from multithreaded collisions. Releaes
// before we add the event so we don't cause a race condition.
{
dlib::auto_mutex lock(*mAssetLock);

AssetPtr old = mAssetMap[aId];
if (old.getObject() != NULL)
mAssets.remove(old);
else
mAssetCounts[aType] += 1;

AssetPtr ptr;
if (aType == "CuttingTool") {
try {
ptr = mXmlParser->parseAsset(aId, aType, aAsset);
}
catch (runtime_error &e) {
sLogger << LERROR << "addAsset: Error parsing asset: " << aAsset << "\n" << e.what();
return false;
}
} else {
ptr.setObject(new Asset(aId, aType, aAsset), true);
ptr->setTimestamp(time);
ptr->setDeviceUuid(aDevice->getUuid());
try {
ptr = mXmlParser->parseAsset(aId, aType, aAsset);
}
catch (runtime_error &e) {
sLogger << LERROR << "addAsset: Error parsing asset: " << aAsset << "\n" << e.what();
return false;
}

AssetPtr &old = mAssetMap[aId];
if (!ptr->isRemoved())
{
if (old.getObject() != NULL)
mAssets.remove(&old);
else
mAssetCounts[aType] += 1;
} else if (old.getObject() == NULL) {
sLogger << LWARN << "Cannot remove non-existent asset";
return false;
}

if (ptr.getObject() == NULL) {
sLogger << LWARN << "Asset could not be created";
return false;
} else {
if (ptr->getTimestamp().empty())
ptr->setTimestamp(time);
if (ptr->getDeviceUuid().empty())
ptr->setDeviceUuid(aDevice->getUuid());
ptr->setAssetId(aId);
ptr->setTimestamp(time);
ptr->setDeviceUuid(aDevice->getUuid());
}

// Check for overflow
if (mAssets.size() >= mMaxAssets)
{
old = mAssets.front();
old = *mAssets.front();
mAssetCounts[old->getType()] -= 1;
mAssets.pop_front();
mAssetMap.erase(old->getAssetId());

// Add secondary keys
AssetKeys &keys = old->getKeys();
AssetKeys::iterator iter;
for (iter = keys.begin(); iter != keys.end(); iter++)
{
AssetIndex &index = mAssetIndices[iter->first];
index.erase(iter->second);
}
}

mAssetMap[aId] = ptr;
mAssets.push_back(ptr);
if (!ptr->isRemoved())
{
AssetPtr &newPtr = mAssetMap[aId];
mAssets.push_back(&newPtr);
}

// Add secondary keys
AssetKeys &keys = ptr->getKeys();
Expand All @@ -530,7 +555,10 @@ bool Agent::addAsset(Device *aDevice, const string &aId, const string &aAsset,
}

// Generate an asset chnaged event.
addToBuffer(aDevice->getAssetChanged(), aType + "|" + aId, time);
if (ptr->isRemoved())
addToBuffer(aDevice->getAssetRemoved(), aType + "|" + aId, time);
else
addToBuffer(aDevice->getAssetChanged(), aType + "|" + aId, time);

return true;
}
Expand All @@ -552,7 +580,7 @@ bool Agent::updateAsset(Device *aDevice, const std::string &aId, AssetChangeList
if (asset.getObject() == NULL)
return false;

if (asset->getType() != "CuttingTool")
if (asset->getType() != "CuttingTool" && asset->getType() != "CuttingToolArchitype")
return false;

CuttingToolPtr tool((CuttingTool*) asset.getObject());
Expand All @@ -573,6 +601,10 @@ bool Agent::updateAsset(Device *aDevice, const std::string &aId, AssetChangeList
return false;
}

// Move it to the front of the queue
mAssets.remove(&asset);
mAssets.push_back(&asset);

tool->setTimestamp(aTime);
tool->setDeviceUuid(aDevice->getUuid());
tool->changed();
Expand All @@ -583,6 +615,33 @@ bool Agent::updateAsset(Device *aDevice, const std::string &aId, AssetChangeList
return true;
}

bool Agent::removeAsset(Device *aDevice, const std::string &aId, const string &aTime)
{
AssetPtr asset;

string time;
if (aTime.empty())
time = getCurrentTime(GMT_UV_SEC);
else
time = aTime;

{
dlib::auto_mutex lock(*mAssetLock);

asset = mAssetMap[aId];
if (asset.getObject() == NULL)
return false;

asset->setRemoved(true);
asset->setTimestamp(aTime);
}

addToBuffer(aDevice->getAssetRemoved(), asset->getType() + "|" + aId, time);

return true;
}


/* Add values for related data items UNAVAILABLE */
void Agent::disconnected(Adapter *anAdapter, std::vector<Device*> aDevices)
{
Expand Down Expand Up @@ -901,13 +960,13 @@ std::string Agent::handleAssets(std::ostream& aOut,
// Return all asssets, first check if there is a type attribute

string type = aQueries["type"];
bool removed = (aQueries.count("removed") > 0 && aQueries["removed"] == "true");

list<AssetPtr>::iterator iter;
list<AssetPtr*>::iterator iter;
for (iter = mAssets.begin(); iter != mAssets.end(); ++iter)
{
if (type.empty() || type == (*iter)->getType())
{
assets.push_back(*iter);
if ((type.empty() || type == (**iter)->getType()) && (removed || !(**iter)->isRemoved())) {
assets.push_back(**iter);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions agent/agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,16 @@ class Agent : public server_http
std::string time = ""
);

// Add an asset to the agent
// Asset management
bool addAsset(Device *aDevice, const std::string &aId, const std::string &aAsset,
const std::string &aType,
const std::string &aTime = "");

bool updateAsset(Device *aDevice, const std::string &aId, AssetChangeList &aList,
const std::string &aTime);

bool removeAsset(Device *aDevice, const std::string &aId, const std::string &aTime);

/* Message when adapter has connected and disconnected */
void disconnected(Adapter *anAdapter, std::vector<Device*> aDevices);
void connected(Adapter *anAdapter, std::vector<Device*> aDevices);
Expand Down Expand Up @@ -290,7 +292,7 @@ class Agent : public server_http
unsigned int mSlidingBufferSize;

/* Asset storage, circ buffer stores ids */
std::list<AssetPtr> mAssets;
std::list<AssetPtr*> mAssets;
AssetIndex mAssetMap;

// Natural key indices for assets
Expand Down
7 changes: 3 additions & 4 deletions agent/asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@

using namespace std;

Asset::Asset(const std::string &aAssetId, const std::string &aType, const std::string &aContent)
Asset::Asset(const std::string &aAssetId, const std::string &aType, const std::string &aContent,
const bool aRemoved)
: mAssetId(aAssetId), mContent(aContent), mType(aType), mRemoved(aRemoved)
{
mAssetId = aAssetId;
mContent = aContent;
mType = aType;
}

Asset::~Asset()
Expand Down
15 changes: 10 additions & 5 deletions agent/asset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Asset : public RefCounted
std::string mType;
std::string mDeviceUuid;
std::string mTimestamp;
bool mRemoved;
AssetKeys mKeys;

public:
Expand All @@ -43,16 +44,19 @@ class Asset : public RefCounted
mAssetId = aOther.mAssetId;
mContent = aOther.mContent;
mType = aOther.mType;
mRemoved = aOther.mRemoved;
}
Asset(const std::string &aAssetId, const std::string &aType, const std::string &aContent);
Asset(const std::string &aAssetId, const std::string &aType, const std::string &aContent,
const bool aRemoved = false);
virtual ~Asset();

std::string &getAssetId() { return mAssetId; }
const std::string &getAssetId() const { return mAssetId; }
virtual std::string &getContent() { return mContent; }
std::string &getType() { return mType; }
const std::string &getType() const { return mType; }
AssetKeys &getKeys() { return mKeys; }
std::string &getDeviceUuid() { return mDeviceUuid; }
std::string &getTimestamp() { return mTimestamp; }
const std::string &getDeviceUuid() const { return mDeviceUuid; }
const std::string &getTimestamp() const { return mTimestamp; }
bool isRemoved() const { return mRemoved; }

bool operator==(const Asset &aOther) {
return mAssetId == aOther.mAssetId;
Expand All @@ -61,6 +65,7 @@ class Asset : public RefCounted
void setAssetId(const std::string &aId) { mAssetId = aId; }
void setDeviceUuid(const std::string &aId) { mDeviceUuid = aId; }
void setTimestamp(const std::string &aTs) { mTimestamp = aTs; }
void setRemoved(bool aRemoved) { mRemoved = aRemoved; }
};

typedef std::map<std::string, AssetPtr> AssetIndex;
Expand Down
4 changes: 3 additions & 1 deletion agent/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ void Component::addDataItem(DataItem& dataItem)
mAvailability = &dataItem;
else if (dataItem.getType() == "ASSET_CHANGED")
mAssetChanged = &dataItem;

else if (dataItem.getType() == "ASSET_REMOVED")
mAssetRemoved = &dataItem;

mDataItems.push_back(&dataItem);
}

Expand Down
2 changes: 2 additions & 0 deletions agent/component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Component
// Cached data items
DataItem *getAvailability() const { return mAvailability; }
DataItem *getAssetChanged() const { return mAssetChanged; }
DataItem *getAssetRemoved() const { return mAssetRemoved; }


/* Add/get description specifications using an attribute map */
Expand Down Expand Up @@ -165,6 +166,7 @@ class Component
Device *mDevice;
DataItem *mAvailability;
DataItem *mAssetChanged;
DataItem *mAssetRemoved;

/* Each component keeps track of it's children in a std::list */
std::list<Component *> mChildren;
Expand Down
10 changes: 3 additions & 7 deletions agent/component_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,9 @@ AttributeList *ComponentEvent::getAttributes()
getline(toParse, token, '|');
mAttributes.push_back(AttributeItem("state", token));
}
else if (mDataItem->isAssetChanged())
else if (mDataItem->isAssetChanged() || mDataItem->isAssetRemoved())
{
istringstream toParse(mRest);
string token;

getline(toParse, token, '|');
mAttributes.push_back(AttributeItem("assetType", token));
mAttributes.push_back(AttributeItem("assetType", mRest));
}
mHasAttributes = true;
}
Expand Down Expand Up @@ -212,7 +208,7 @@ void ComponentEvent::convertValue(const string& value)
mValue = value;
}
else if (mIsTimeSeries || mDataItem->isCondition() || mDataItem->isAlarm() ||
mDataItem->isMessage() || mDataItem->isAssetChanged())
mDataItem->isMessage() || mDataItem->isAssetChanged() || mDataItem->isAssetRemoved())
{
string::size_type lastPipe = value.rfind('|');

Expand Down
5 changes: 3 additions & 2 deletions agent/cutting_tool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ class CuttingItem : public RefCounted {

class CuttingTool : public Asset {
public:
CuttingTool(const std::string &aAssetId, const std::string &aType, const std::string &aContent)
: Asset(aAssetId, aType, aContent) {}
CuttingTool(const std::string &aAssetId, const std::string &aType, const std::string &aContent,
bool aRemoved = false)
: Asset(aAssetId, aType, aContent, aRemoved) {}
~CuttingTool();

void addIdentity(const std::string &aKey, const std::string &aValue);
Expand Down
Loading

0 comments on commit 0e6613a

Please sign in to comment.