Commit 9362bf08 by amir

Add loading fsm from stream/string

parent a2b7c5a9
...@@ -76,7 +76,8 @@ struct StateIndex ...@@ -76,7 +76,8 @@ struct StateIndex
bool isValid() bool isValid()
{ {
return (uiStateIndex != nsConstants::C_NO_ENTRY && return (uiStateIndex != nsConstants::C_NO_ENTRY &&
uiStateFlowIndex != nsConstants::C_NO_ENTRY); uiStateFlowIndex != nsConstants::C_NO_ENTRY &&
!fsmId.empty() && !stateName.empty());
} }
bool operator==(const StateIndex &rhs) const { bool operator==(const StateIndex &rhs) const {
......
...@@ -77,6 +77,43 @@ RetStat SehEngine::BuildSingleFlowTable(string flowPrefix, string flowFile) { ...@@ -77,6 +77,43 @@ RetStat SehEngine::BuildSingleFlowTable(string flowPrefix, string flowFile) {
return retStat; return retStat;
} }
RetStat SehEngine::BuildSingleFlow(string flowPrefix, string& flowFSM) {
RetStat retStat;
CallFlow* p_cf = nullptr;
CallFlow** pp_cf = (CallFlow**)GetFromMap(callFlowMap_,flowPrefix);
if(pp_cf && *pp_cf)
{
/**
* updating
*/
(*pp_cf)->Reset();
(*pp_cf)->fsmId = flowPrefix;
p_cf = *pp_cf;
}
else
{
/**
* new call flow
*/
p_cf = new CallFlow(flowPrefix);
p_cf->flowIndex = maxNumberOfCallFlows_++;
callFlowMap_[flowPrefix] = p_cf;
callFlowArray_.push_back(p_cf);
}
/**
* now resolve the builder
*/
if(p_callFlowBuilder_ == nullptr) {
string xmlPrefix = "</xml>";
if (flowFSM.rfind(xmlPrefix) != string::npos)
p_callFlowBuilder_ = new XMLCallFlowBuilder();
else
p_callFlowBuilder_ = new JsonCallFlowBuilder();
}
retStat = p_callFlowBuilder_->BuildFlowTableFromString(flowFSM.c_str(),p_cf,p_baseSEHObject_);
return retStat;
}
ICallFlowBuilder *SehEngine::createCallFlowBuilder(string flowFile) { ICallFlowBuilder *SehEngine::createCallFlowBuilder(string flowFile) {
int lastIndexOf = flowFile.find_last_of('.'); int lastIndexOf = flowFile.find_last_of('.');
if (lastIndexOf != string::npos) if (lastIndexOf != string::npos)
...@@ -458,6 +495,23 @@ RetStat SehEngine::InitMultiFlows(string &flowsFileName, map<string, IBaseSEH *> ...@@ -458,6 +495,23 @@ RetStat SehEngine::InitMultiFlows(string &flowsFileName, map<string, IBaseSEH *>
return retStat; return retStat;
} }
RetStat SehEngine::InitSingleFlow(string &flowPrefix, string& flowFSM, IBaseSEH *p_baseSEH) {
this->baseSEHObjectMap_[flowPrefix] = p_baseSEH;
//InitMembers();// InitMultiFlowsMembers();
activateActionData_.Reset();
eventAction_.Reset();
p_baseSEHObject_ = p_baseSEH;
maxNumberOfCallFlows_ = callFlowMap_.size();
RetStat retStat = BuildSingleFlow(flowPrefix,flowFSM);
if (retStat.Success())
{
retStat = ResolveNextStateIndexes();
if (retStat.Fail())
SEH_METHOD_ERROR("Failed in ResolveNextStateIndexes");
}
return retStat;
}
RetStat SehEngine::InitMultiFlows(map<string, string> &flowFilesMap, map<string, IBaseSEH *> &baseSehMap) { RetStat SehEngine::InitMultiFlows(map<string, string> &flowFilesMap, map<string, IBaseSEH *> &baseSehMap) {
maxNumberOfCallFlows_ = 1; // will be resolved from the flow file maxNumberOfCallFlows_ = 1; // will be resolved from the flow file
this->baseSEHObjectMap_ = baseSehMap; this->baseSEHObjectMap_ = baseSehMap;
...@@ -497,10 +551,13 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) { ...@@ -497,10 +551,13 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) {
********************/ ********************/
if(!stateIndex.isValid()) if(!stateIndex.isValid())
{ {
if(GetStateIndex(stateIndex.fsmId,stateIndex.stateName,stateIndex).Fail())
{
SEH_METHOD_ERROR("-\tInvalid State index"); SEH_METHOD_ERROR("-\tInvalid State index");
retStatus.SetFail(); retStatus.SetFail();
return retStatus; return retStatus;
} }
}
/****************************** /******************************
* Reseting the working params Getting the Session State * Reseting the working params Getting the Session State
...@@ -520,62 +577,68 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) { ...@@ -520,62 +577,68 @@ RetStat SehEngine::HandleEvent(StateIndex& stateIndex, string& eventStr) {
* and setting the BaseSEH object * and setting the BaseSEH object
***********************************************/ ***********************************************/
this->p_state_ = p_callFlow->stateArray[this->p_stateIndex_->uiStateIndex].get(); this->p_state_ = p_callFlow->stateArray[this->p_stateIndex_->uiStateIndex].get();
/**
* validate names, maybe the flow has changed since last session event
*/
if(p_stateIndex_->fsmId == p_callFlow->fsmId && p_stateIndex_->stateName == p_state_->stateName) { if(p_stateIndex_->fsmId == p_callFlow->fsmId && p_stateIndex_->stateName == p_state_->stateName) {
p_eventData_ = (EventData *) GetFromMap(this->p_state_->eventsMap, eventStr); retStatus = GetEventAndActivateActions(eventStr, retStatus, p_callFlow);
this->p_baseSEHObject_ = p_callFlow->p_baseSEHObject;
} else
{
if(GetStateIndex(p_stateIndex_->fsmId,p_stateIndex_->stateName,*p_stateIndex_).Success())
retStatus = GetEventAndActivateActions(eventStr, retStatus, p_callFlow);
else {
SEH_METHOD_ERROR("-\tState index mismatch with flow fsm and state name");
retStatus.SetFail();
}
}
} else
{
SEH_METHOD_ERROR("-\tWrong State index");
retStatus.SetFail();
//return retStatus;
}
} else
{
SEH_METHOD_ERROR("-\tWrong Flow index");
retStatus.SetFail();
}
return retStatus;
}
RetStat &SehEngine::GetEventAndActivateActions(string &eventStr, RetStat &retStatus, const CallFlow *p_callFlow) {
p_eventData_ = (EventData *) GetFromMap(p_state_->eventsMap, eventStr);
p_baseSEHObject_ = p_callFlow->p_baseSEHObject;
//this->activateActionData_.object = p_callFlow->baseSEHObject;; //this->activateActionData_.object = p_callFlow->baseSEHObject;;
string &eventName = eventStr; //this.baseSEHObject.resolveEventName(iEvent); string &eventName = eventStr; //this.baseSEHObject.resolveEventName(iEvent);
if (!eventName.empty()) if (!eventName.empty())
SEH_METHOD_LOG("-\tState/Event: ", this->p_state_->stateName, '/', eventName); SEH_METHOD_LOG("-\tState/Event: ", p_state_->stateName, '/', eventName);
/********************************************** /**********************************************
* if no implementation for this State/Event then looking if * if no implementation for this State/Event then looking if
* there is a BaseState * there is a BaseState
*********************************************/ *********************************************/
if ((this->p_eventData_ == nullptr || this->p_eventData_->getNumOfActions() == 0) if ((p_eventData_ == nullptr || p_eventData_->getNumOfActions() == 0)
&& (this->p_state_->baseState.IsValid())) { && (p_state_->baseState.IsValid())) {
this->p_stateIndex_ = &this->p_state_->baseState.stateIndex; p_stateIndex_ = &p_state_->baseState.stateIndex;
this->p_state_ = p_callFlow->stateArray[this->p_stateIndex_->uiStateIndex].get(); p_state_ = p_callFlow->stateArray[p_stateIndex_->uiStateIndex].get();
this->p_eventData_ = (EventData *) GetFromMap(this->p_state_->eventsMap, p_eventData_ = (EventData *) GetFromMap(p_state_->eventsMap,
eventStr); // eventCellsArray[iEvent]; eventStr); // eventCellsArray[iEvent];
} }
if (this->p_eventData_ != nullptr) { if (p_eventData_ != nullptr) {
// Logger.severe("SEHEngine::HandleEvent-\tEvent: "
// + eventName + " Not Implemented for State: "
// + this.statePtr.stateName);
// retStatus.setFail();
// return retStatus;
// }
/************************* /*************************
* Get & Activate Actions * Get & Activate Actions
************************/ ************************/
retStatus = ActivateActions(*this->p_stateIndex_); retStatus = ActivateActions(*p_stateIndex_);
} else { } else {
SEH_METHOD_ERROR("-\tEvent: ", eventName, " Not Implemented for State: ", SEH_METHOD_ERROR("-\tEvent: ", eventName, " Not Implemented for State: ",
this->p_state_->stateName); p_state_->stateName);
retStatus.SetFail(); retStatus.SetFail();
} }
} else
{
SEH_METHOD_ERROR("-\tState index mismatch with flow fsm and state name");
retStatus.SetFail();
}
} else
{
SEH_METHOD_ERROR("-\tWrong State index");
retStatus.SetFail();
//return retStatus;
}
} else
{
SEH_METHOD_ERROR("-\tWrong Flow index");
retStatus.SetFail();
}
return retStatus; return retStatus;
} }
...@@ -700,3 +763,4 @@ RetStat SehEngine::GetStateIndex(const char *p_fsmId, const char *p_stateName, S ...@@ -700,3 +763,4 @@ RetStat SehEngine::GetStateIndex(const char *p_fsmId, const char *p_stateName, S
string stateName = p_stateName; string stateName = p_stateName;
return GetStateIndex(fsmId,stateName,stateIndex); return GetStateIndex(fsmId,stateName,stateIndex);
} }
...@@ -57,7 +57,16 @@ private: ...@@ -57,7 +57,16 @@ private:
*/ */
RetStat BuildSingleFlowTable(string flowPrefix, string flowFile); RetStat BuildSingleFlowTable(string flowPrefix, string flowFile);
ICallFlowBuilder* createCallFlowBuilder(string flowFile); ICallFlowBuilder* createCallFlowBuilder(string flowFile);
RetStat ReadAndCreateFlowsFromFile(); RetStat ReadAndCreateFlowsFromFile();
/**
* building call flow from string
* @param flowPrefix
* @param flowFSM
* @return
*/
RetStat BuildSingleFlow(string flowPrefix, string& flowFSM);
/** /**
* Resolving the next state index from the state name here there is only one * Resolving the next state index from the state name here there is only one
...@@ -115,6 +124,7 @@ public: ...@@ -115,6 +124,7 @@ public:
* @return * @return
*/ */
RetStat HandleEvent(StateIndex& stateIndex, string& eventStr); RetStat HandleEvent(StateIndex& stateIndex, string& eventStr);
/** /**
* Handling the State/Event : This method is what this is all about, getting * Handling the State/Event : This method is what this is all about, getting
* the State/Event and activating the resolved actions and setting the next * the State/Event and activating the resolved actions and setting the next
...@@ -162,6 +172,17 @@ public: ...@@ -162,6 +172,17 @@ public:
RetStat ResolveRecursiveNextState(EventData &eventData); RetStat ResolveRecursiveNextState(EventData &eventData);
RetStat ResolveNextState(NextState &nextState); RetStat ResolveNextState(NextState &nextState);
/**
* init flow from fsm string
* @param flowPrefix
* @param flowFSM
* @param p_baseSEH
* @return
*/
RetStat InitSingleFlow(string &flowPrefix, string& flowFSM, IBaseSEH *p_baseSEH);
RetStat &GetEventAndActivateActions(string &eventStr, RetStat &retStatus, const CallFlow *p_callFlow);
}; };
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
#include <iostream> #include <iostream>
#include <functional> #include <functional>
#include <vector> #include <vector>
#include <cstring> //#include <cstring>
#include <limits.h> #include <limits.h>
#include <mhash.h> #include <mhash.h>
#include <ctime> #include <ctime>
#include <fstream>
#include <sstream>
#include "../src/defs/seh_types.h" #include "../src/defs/seh_types.h"
#include "../src/seh/seh_engine.h" #include "../src/seh/seh_engine.h"
...@@ -130,6 +132,8 @@ public: ...@@ -130,6 +132,8 @@ public:
INTINT_FUNC resolveFunc() { return std::bind(&TestSub::subbing,this,_1,_2); } INTINT_FUNC resolveFunc() { return std::bind(&TestSub::subbing,this,_1,_2); }
}; };
void TestFSMBuffer(basic_ifstream<char> flowFileName);
void simple_test() void simple_test()
{ {
...@@ -150,6 +154,22 @@ std::string getexepath() ...@@ -150,6 +154,22 @@ std::string getexepath()
return std::string( result, (count > 0) ? count : 0 ); return std::string( result, (count > 0) ? count : 0 );
} }
RetStat TestFSMBuffer(string& fsmId,
string& flowFileName,
SehEngine* fsmEngine,
IBaseSEH* p_BaseSEH) {
RetStat stat;
std::ifstream jsonFile(flowFileName);
if(jsonFile.is_open())
{
std::stringstream buffer;
buffer << jsonFile.rdbuf();
string flowFsm = buffer.str();
stat = fsmEngine->InitSingleFlow(fsmId,flowFsm,p_BaseSEH);
}
return stat;
}
int main() { int main() {
RetStat stat; RetStat stat;
int TEST_REP = 1000000; int TEST_REP = 1000000;
...@@ -165,10 +185,20 @@ int main() { ...@@ -165,10 +185,20 @@ int main() {
map<string,string> flowFilesMap; map<string,string> flowFilesMap;
map<string,IBaseSEH*> flowsSEHMap; map<string,IBaseSEH*> flowsSEHMap;
//flowFilesMap.put("Test", "src/test/resources/seh/TestSEH.xml"); //flowFilesMap.put("Test", "src/test/resources/seh/TestSEH.xml");
flowFilesMap["Test"] = "/home/amir/git/ipgallery/common/cpp/seh/test/resources/TestSEH.json"; string flowFile = "/home/amir/git/ipgallery/common/cpp/seh/test/resources/TestSEH.json";
flowsSEHMap["Test"] = &testSEH; std::string flowPrefix = "Test";
bool useBufferFsm = true;
if(useBufferFsm) {
stat = TestFSMBuffer(flowPrefix,flowFile, fsmEngine,(IBaseSEH*)&testSEH);
} else {
flowFilesMap[flowPrefix] = flowFile;
flowsSEHMap[flowPrefix] = &testSEH;
stat = fsmEngine->InitMultiFlows(flowFilesMap, flowsSEHMap); stat = fsmEngine->InitMultiFlows(flowFilesMap, flowsSEHMap);
}
if(stat.Success()) { if(stat.Success()) {
stat = fsmEngine->GetStateIndex("Test","Idle",state); stat = fsmEngine->GetStateIndex("Test","Idle",state);
if(stat.Success()) { if(stat.Success()) {
...@@ -192,3 +222,4 @@ int main() { ...@@ -192,3 +222,4 @@ int main() {
} }
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment