void Device::addDeviceDataItem(DataItem& dataItem) {
  if (!dataItem.getSource().empty())
    mDeviceDataItemsBySource[dataItem.getSource()] = &dataItem;
  if (!dataItem.getName().empty())
    mDeviceDataItemsByName[dataItem.getName()] = &dataItem;
  
  if (mDeviceDataItemsById[dataItem.getId()] != NULL) {
    sLogger << dlib::LERROR << "Duplicate data item id: " << dataItem.getId() << " for device " 
            << mName << ", skipping";
  } else {
    mDeviceDataItemsById[dataItem.getId()] = &dataItem;
  }
}
Beispiel #2
0
/* Agent public methods */
Agent::Agent(const string& configXmlPath)
{
  try
  {
    // Load the configuration for the Agent
    mConfig = new XmlParser(configXmlPath);
  }
  catch (exception & e)
  {
    logEvent("Agent::Agent",
      "Error loading xml configuration: " + configXmlPath);
    delete mConfig;
    throw (string) e.what();
  }
  
  // Grab data from configuration
  mDevices = mConfig->getDevices();
  
  list<Device *>::iterator device;
  for (device = mDevices.begin(); device != mDevices.end(); device++) 
  {
    mDeviceMap[(*device)->getName()] = *device;
    
    std::map<string, DataItem*> items = (*device)->getDeviceDataItems();
    
    std::map<string, DataItem *>::iterator item;
    for (item = items.begin(); item != items.end(); item++)
    {
      DataItem *d = item->second;
      mDataItemMap[d->getId()] = d;
    }
  }
  
  // Unique id number for agent instance
  mInstanceId = getCurrentTimeInSec();
  
  // Sequence number and sliding buffer for data
  mSequence = 1;
  mSlidingBuffer = new sliding_buffer_kernel_1<ComponentEvent *>();
  mSlidingBuffer->set_size(SLIDING_BUFFER_EXP);
  
  // Initialize the buffer
  for (unsigned int i = 0; i < mSlidingBuffer->size(); i++)
  {
    (*mSlidingBuffer)[i] = 0;
  }
  
  // Mutex used for synchronized access to sliding buffer and sequence number
  mSequenceLock = new dlib::mutex;
}
Beispiel #3
0
/* Add values for related data items UNAVAILABLE */
void Agent::disconnected(Adapter *anAdapter, vector<Device*> aDevices)
{
    string time = getCurrentTime(GMT_UV_SEC);
    sLogger << LDEBUG << "Disconnected from adapter, setting all values to UNAVAILABLE";

    std::vector<Device*>::iterator iter;
    for (iter = aDevices.begin(); iter != aDevices.end(); ++iter) {
        std::map<std::string, DataItem *> dataItems = (*iter)->getDeviceDataItems();
        std::map<std::string, DataItem*>::iterator dataItemAssoc;
        for (dataItemAssoc = dataItems.begin(); dataItemAssoc != dataItems.end(); ++dataItemAssoc)
        {
            DataItem *dataItem = (*dataItemAssoc).second;
            if (dataItem != NULL && (dataItem->getDataSource() == anAdapter ||
                                     (anAdapter->isAutoAvailable() &&
                                      dataItem->getDataSource() == NULL &&
                                      dataItem->getType() == "AVAILABILITY")))
            {
                ComponentEventPtr *ptr = mLatest.getEventPtr(dataItem->getId());

                if (ptr != NULL) {
                    const string *value = NULL;
                    if (dataItem->isCondition()) {
                        if ((*ptr)->getLevel() != ComponentEvent::UNAVAILABLE)
                            value = &sConditionUnavailable;
                    } else if (dataItem->hasConstraints()) {
                        std::vector<std::string> &values = dataItem->getConstrainedValues();
                        if (values.size() > 1 && (*ptr)->getValue() != sUnavailable)
                            value = &sUnavailable;
                    } else if ((*ptr)->getValue() != sUnavailable) {
                        value = &sUnavailable;
                    }

                    if (value != NULL)
                        addToBuffer(dataItem, *value, time);
                }
            } else if (dataItem == NULL) {
                sLogger << LWARN << "No data Item for " << (*dataItemAssoc).first;
            }
        }
    }
}
void Checkpoint::addComponentEvent (ComponentEvent *anEvent)
{
    if ( mHasFilter )
    {
        if ( mFilter.count(anEvent->getDataItem( )->getId( )) == 0 )
        {
            return;
        }
    }

    DataItem *         item = anEvent->getDataItem( );
    string             id   = item->getId( );
    ComponentEventPtr *ptr  = mEvents[id];

    if ( ptr != NULL )
    {
        bool assigned = false;

        if ( item->isCondition( ) )
        {
            // Chain event only if it is normal or unavailable and the
            // previous condition was not normal or unavailable
            if ( ( ( *ptr )->getLevel( ) != ComponentEvent::NORMAL ) &&
                 ( anEvent->getLevel( ) != ComponentEvent::NORMAL ) &&
                 ( ( *ptr )->getLevel( ) != ComponentEvent::UNAVAILABLE ) &&
                 ( anEvent->getLevel( ) != ComponentEvent::UNAVAILABLE )
                 )
            {
                // Check to see if the native code matches an existing
                // active condition
                ComponentEvent *e = ( *ptr )->find(anEvent->getCode( ));

                if ( e != NULL )
                {
                    // Replace in chain.
                    ComponentEvent *n = ( *ptr )->deepCopyAndRemove(e);

                    // Check if this is the only event...
                    ( *ptr ) = n;

                    if ( n != NULL )
                    {
                        n->unrefer( );
                    }
                }

                // Chain the event
                if ( ptr->getObject( ) != NULL )
                {
                    anEvent->appendTo(*ptr);
                }
            }
            else if ( anEvent->getLevel( ) == ComponentEvent::NORMAL )
            {
                // Check for a normal that clears an active condition by code
                if ( anEvent->getCode( )[0] != '\0' )
                {
                    ComponentEvent *e = ( *ptr )->find(anEvent->getCode( ));

                    if ( e != NULL )
                    {
                        // Clear the one condition by removing it from the chain
                        ComponentEvent *n = ( *ptr )->deepCopyAndRemove(e);
                        ( *ptr ) = n;

                        if ( n != NULL )
                        {
                            n->unrefer( );
                        }
                        else
                        {
                            // Need to put a normal event in with no code since this
                            // is the last one.
                            n = new ComponentEvent(*anEvent);
                            n->normal( );
                            ( *ptr ) = n;
                            n->unrefer( );
                        }
                    }
                    else
                    {
                        // Not sure if we should register code specific normals if
                        // previous normal was not found
                        // (*ptr) = anEvent;
                    }
                    assigned = true;
                }
            }
        }

        if ( !assigned )
        {
            ( *ptr ) = anEvent;
        }
    }
    else
    {
        mEvents[id] = new ComponentEventPtr(anEvent);
    }
}
Beispiel #5
0
/* Agent public methods */
Agent::Agent(const string& configXmlPath, int aBufferSize, int aMaxAssets, int aCheckpointFreq)
    : mPutEnabled(false), mLogStreamData(false)
{
    try
    {
        // Load the configuration for the Agent
        mXmlParser = new XmlParser();
        mDevices = mXmlParser->parseFile(configXmlPath);
        vector<Device *>::iterator device;
        std::set<std::string> uuids;
        for (device = mDevices.begin(); device != mDevices.end(); ++device)
        {
            if (uuids.count((*device)->getUuid()) > 0)
                throw runtime_error("Duplicate UUID: " + (*device)->getUuid());

            uuids.insert((*device)->getUuid());
        }
    }
    catch (runtime_error & e)
    {
        sLogger << LFATAL << "Error loading xml configuration: " + configXmlPath;
        sLogger << LFATAL << "Error detail: " << e.what();
        cerr << e.what() << endl;
        throw e;
    }
    catch (exception &f)
    {
        sLogger << LFATAL << "Error loading xml configuration: " + configXmlPath;
        sLogger << LFATAL << "Error detail: " << f.what();
        cerr << f.what() << endl;
        throw f;
    }

    // Grab data from configuration
    string time = getCurrentTime(GMT_UV_SEC);

    // Unique id number for agent instance
    mInstanceId = getCurrentTimeInSec();

    // Sequence number and sliding buffer for data
    mSequence = 1;
    mSlidingBufferSize = 1 << aBufferSize;
    mSlidingBuffer = new sliding_buffer_kernel_1<ComponentEventPtr>();
    mSlidingBuffer->set_size(aBufferSize);
    mCheckpointFreq = aCheckpointFreq;
    mCheckpointCount = (mSlidingBufferSize / aCheckpointFreq) + 1;

    // Asset sliding buffer
    mMaxAssets = aMaxAssets;

    // Create the checkpoints at a regular frequency
    mCheckpoints = new Checkpoint[mCheckpointCount];

    // Mutex used for synchronized access to sliding buffer and sequence number
    mSequenceLock = new dlib::mutex;
    mAssetLock = new dlib::mutex;

    // Add the devices to the device map and create availability and
    // asset changed events if they don't exist
    vector<Device *>::iterator device;
    for (device = mDevices.begin(); device != mDevices.end(); ++device)
    {
        mDeviceMap[(*device)->getName()] = *device;

        // Make sure we have two device level data items:
        // 1. Availability
        // 2. AssetChanged
        if ((*device)->getAvailability() == NULL)
        {
            // Create availability data item and add it to the device.
            std::map<string,string> attrs;
            attrs["type"] = "AVAILABILITY";
            attrs["id"] = (*device)->getId() + "_avail";
            attrs["category"] = "EVENT";

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

        if ((*device)->getAssetChanged() == NULL)
        {
            // Create availability data item and add it to the device.
            std::map<string,string> attrs;
            attrs["type"] = "ASSET_CHANGED";
            attrs["id"] = (*device)->getId() + "_asset_chg";
            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,
                             mMaxAssets,
                             mAssets.size(),
                             mSequence, mDevices));

    /* Initialize the id mapping for the devices and set all data items to UNAVAILABLE */
    for (device = mDevices.begin(); device != mDevices.end(); ++device)
    {
        const std::map<string, DataItem*> &items = (*device)->getDeviceDataItems();
        std::map<string, DataItem *>::const_iterator item;

        for (item = items.begin(); item != items.end(); ++item)
        {
            // Check for single valued constrained data items.
            DataItem *d = item->second;
            const string *value = &sUnavailable;
            if (d->isCondition()) {
                value = &sConditionUnavailable;
            } else if (d->hasConstraints()) {
                std::vector<std::string> &values = d->getConstrainedValues();
                if (values.size() == 1)
                    value = &values[0];
            }

            addToBuffer(d, *value, time);
            if (mDataItemMap.count(d->getId()) == 0)
                mDataItemMap[d->getId()] = d;
            else {
                sLogger << LFATAL << "Duplicate DataItem id " << d->getId() <<
                        " for device: " << (*device)->getName() << " and data item name: " <<
                        d->getName();
                exit(1);
            }
        }
    }
}