AbstractRTAction.cpp
Go to the documentation of this file.00001
00002
00003 #include <fesa-core/RealTime/AbstractRTAction.h>
00004
00005 #include <fesa-core/RealTime/RTEvent.h>
00006 #include <fesa-core/RealTime/AbstractRTEquipment.h>
00007 #include <fesa-core/DataStore/GlobalDevice.h>
00008 #include <fesa-core/DataStore/EquipmentData.h>
00009 #include <fesa-core/Core/NotificationIDManager.h>
00010 #include <fesa-core/Core/NotificationProducer.h>
00011 #include <fesa-core/Core/AbstractServiceLocator.h>
00012 #include <fesa-core/Core/MessageTypes.h>
00013 #include <fesa-core/Diagnostic/Diagnostics.h>
00014 #include <fesa-core/Core/OnDemandProducer.h>
00015
00016 #include <cmw-log/Logger.h>
00017
00018
00019 namespace
00020 {
00021
00022 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.RealTime.AbstractRTAction");
00023 const std::string diagTopic = fesa::DiagnosticUtils::rtActionProfilingStr;
00024 }
00025
00026
00027 namespace fesa
00028 {
00029
00030 AbstractRTAction::AbstractRTAction(RTActionConfig& rtActionConfig, const AbstractServiceLocator* serviceLocator, const std::map<std::string, const AbstractServiceLocator*> serviceLocatorRelatedClasses) :
00031 AbstractAction(rtActionConfig.actionName_,rtActionConfig.className_,serviceLocator,serviceLocatorRelatedClasses),
00032 eventName_(rtActionConfig.eventName_),
00033 selectionCriterion_(rtActionConfig.selectionCriterion_),
00034 manuallyNotifiedPropertiesCol_(rtActionConfig.manuallyNotifiedPropertiesCol_),
00035 eventSourceName_(rtActionConfig.eventSourceName_),
00036 abstractDeviceCol_(rtActionConfig.deviceCol_),
00037 globalDevice_(rtActionConfig.globalDevice_),
00038 manualNotificationMessage_(NULL),
00039 automaticallyNotifiedPropertiesCol_(rtActionConfig.automaticallyNotifiedPropertiesCol_)
00040
00041 {
00042 NotificationIDManager* notIDGen = NotificationIDManager::getInstance();
00043
00044 std::set<std::string> deviceNames;
00045 for (std::vector<AbstractDevice*>::iterator devIter = abstractDeviceCol_.begin(); devIter != abstractDeviceCol_.end(); devIter++)
00046 {
00047 deviceNames.insert((*devIter)->getName());
00048 }
00049
00050
00051 if (rtActionConfig.isGlobalPropertyToBeNotified_)
00052 deviceNames.insert(globalDevice_->getName());
00053
00054 if (!automaticallyNotifiedPropertiesCol_.empty())
00055 notificationID_ = notIDGen->createNotificationID(automaticallyNotifiedPropertiesCol_, deviceNames, className_);
00056 else
00057 notificationID_ = NO_NOTIFICATION;
00058
00059 theNotificationProducer_ = NotificationProducer::getInstance();
00060
00061
00062 devicesShareTimingDomain_ = true;
00063 timingDomain_.assign("Undefined");
00064 for (uint32_t i = 0; i < (abstractDeviceCol_.size()); i++)
00065 {
00066 if ((abstractDeviceCol_[i])->isMultiplexed())
00067 {
00068 if (timingDomain_.compare(abstractDeviceCol_[i]->timingDomain.getAsString()))
00069 {
00070
00071 if (!timingDomain_.compare("Undefined"))
00072 {
00073 timingDomain_.assign(abstractDeviceCol_[i]->timingDomain.getAsString());
00074 }
00075 else
00076 {
00077 devicesShareTimingDomain_ = false;
00078 timingDomain_.assign("Undefined");
00079 break;
00080 }
00081 }
00082 }
00083 }
00084 if (globalDevice_->isMultiplexed() && devicesShareTimingDomain_ == true)
00085 {
00086 if (timingDomain_.compare(globalDevice_->timingDomain.getAsString()))
00087 {
00088 devicesShareTimingDomain_ = false;
00089 timingDomain_.assign("Undefined");
00090 }
00091 }
00092
00093 if (!manuallyNotifiedPropertiesCol_.empty())
00094 {
00095 this->manualNotificationMessage_ = new ManualNotificationMessage(rtActionConfig.className_);
00096 }
00097 }
00098
00099 AbstractRTAction::~AbstractRTAction()
00100 {
00101
00102 std::vector<AbstractDevice*>::iterator devices;
00103
00104
00105 manuallyNotifiedPropertiesCol_.clear();
00106 automaticallyNotifiedPropertiesCol_.clear();
00107 theNotificationProducer_ = NULL;
00108 }
00109
00110 void AbstractRTAction::executeAction(RTEvent* event)
00111 {
00112
00113 std::string ctxTimingDomainName = event->getMultiplexingContext()->getTimingDomainName();
00114 if (!ctxTimingDomainName.empty())
00115 {
00116 if (devicesShareTimingDomain_ == false)
00117 {
00118 throw FesaException(__FILE__, __LINE__, FesaErrorDevColHasMultipleTimingDomains.c_str());
00119 }
00120 else
00121 {
00122 if (timingDomain_.compare("Undefined"))
00123 {
00124 if (timingDomain_.compare(ctxTimingDomainName))
00125 {
00126 throw FesaException(__FILE__, __LINE__, FesaErrorInconsistentTimingDomain.c_str());
00127 }
00128 }
00129 }
00130 }
00131 const boost::shared_ptr<Diagnostics>& diagnostics = AbstractEquipment::getInstance()->getDiagnostics();
00132 DiagnosticUtils::DiagnosticMessage diagMsg;
00133 diagMsg.side = DiagnosticUtils::framework;
00134 diagMsg.source = DiagnosticUtils::rt;
00135 diagMsg.name = name_;
00136 diagMsg.action = DiagnosticUtils::start;
00137 diagMsg.msg = "";
00138 diagnostics->log(diagTopic, diagMsg);
00139
00140 serviceLocator_->synchronizeSettingFields(*(event->getMultiplexingContext()));
00141
00142 if (this->manualNotificationMessage_ != NULL )
00143 {
00144 this->manualNotificationMessage_->reset();
00145 }
00146
00147 try
00148 {
00149 execute(event);
00150 (completedActionCount_.current_)++;
00151
00152
00153 triggerAllAutomaticallyTriggeredOnDemandEventSources(event->getMultiplexingContext());
00154
00155 if (notificationID_ != NO_NOTIFICATION && automaticallyNotifiedPropertiesCol_.empty() == false)
00156 {
00157 EquipmentData* eqData = EquipmentData::getInstance();
00158 if (*(eqData->serverUp_))
00159 {
00160 theNotificationProducer_->sendAutomaticNotification(notificationID_, *event->getMultiplexingContext(), 0);
00161 if(logger.isLoggable(CMW::Log::Level::LL_TRACE))
00162 {
00163 std::ostringstream msg;
00164 msg << "Notifying the server from " << className_ << "::" << name_ << " (id=" << notificationID_ << ").";
00165 LOG_TRACE_IF(logger, msg.str());
00166 }
00167 }
00168 }
00169 else if (logger.isLoggable(CMW::Log::Level::LL_TRACE))
00170 {
00171 std::ostringstream msg;
00172 msg << "No server notification for " << className_ << "::" << name_ << ": id=" << notificationID_
00173 << " & autoNotification=" << automaticallyNotifiedPropertiesCol_.empty() << ".";
00174 LOG_TRACE_IF(logger, msg.str());
00175 }
00176 }
00177 catch (FesaException& ex)
00178 {
00179 abortedActionCount_++;
00180 diagMsg.action = DiagnosticUtils::stop;
00181 diagnostics->log(diagTopic, diagMsg);
00182 throw;
00183 }
00184 diagMsg.action = DiagnosticUtils::stop;
00185 diagnostics->log(diagTopic, diagMsg);
00186 }
00187
00188 void AbstractRTAction::sendManualNotification(MultiplexingContext* muxContext)
00189 {
00190
00191 EquipmentData* eqData = EquipmentData::getInstance();
00192 if (!(*(eqData->serverUp_)))
00193 {
00194 return;
00195 }
00196
00197 if (this->manualNotificationMessage_ != NULL)
00198 {
00199 this->manualNotificationMessage_->muxContext_ = muxContext;
00200 theNotificationProducer_->sendManualNotification(*manualNotificationMessage_);
00201 }
00202
00203 }
00204
00205 }