EntityInstance.cpp
Go to the documentation of this file.
1// Header
2#include "EntityInstance.h"
3
4// STD / STL
5#include <SimoxUtility/algorithm/string/string_tools.h>
6
7// ArmarX
10
13
15{
16 EntityInstance::EntityInstance(const std::string& exportName,
17 const armem::MemoryID& id /* UNESCAPED */,
18 const std::shared_ptr<Processors>& filters,
19 const std::shared_ptr<persistence::MemoryPersistenceStrategy>& persistenceStrategy) :
20 EntityInstanceBase(exportName, id, filters),
21 persistenceStrategy_(persistenceStrategy)
22 {
23 //start();
24 }
25
26 void
28 {
30
31 int index = std::stoi(getMemoryID().getEntityInstanceID().getLeafItem());
32
33 armem::wm::EntityInstance wmEntityInstance = armem::wm::EntityInstance(index, wmEntitySnapshot.id());
34
35 // add instance. Do not set data, since we only return references
36 wmEntitySnapshot.addInstance(wmEntityInstance);
37 }
38
39 void
41 {
43
44 ARMARX_DEBUG << "Resolve entity instance id=" << id().cleanID().str();
45
46 std::string origin = "undefined3";
47
48 auto& dictConverter = processors->defaultObjectConverter;
49
50
51 aron::data::DictPtr datadict = nullptr;
52 aron::data::DictPtr metadatadict = nullptr;
53
54
55 std::string dataFilename = (persistence::MemoryPersistenceStrategy::DATA_FILENAME + dictConverter.suffix);
56 std::string metadataFilename = (persistence::MemoryPersistenceStrategy::METADATA_FILENAME + dictConverter.suffix);
57
58 if (persistenceStrategy_->containsItem(id(), dataFilename))
59 {
60 auto datafilecontent = persistenceStrategy_->retrieveItem(id(), dataFilename);
61
62 try
63 {
64 auto dataaron = dictConverter.convert({datafilecontent, ""}, {});
65 datadict = aron::data::Dict::DynamicCastAndCheck(dataaron);
66 }
67 catch (std::exception& ex)
68 {
69 ARMARX_ERROR << "Exception during conversion from file into json object. At entity instance=" << id().cleanID().str() << ", file=" << dataFilename << ", error message=" << ex.what();
70 return;
71 }
72 }
73 else
74 {
75 ARMARX_WARNING << "Could not find the data file '" << dataFilename
76 << "'. Continuing without data.";
77 }
78
79 if (persistenceStrategy_->containsItem(id(), metadataFilename))
80 {
81 auto itemResult = persistenceStrategy_->retrieveItemWithOrigin(id(), metadataFilename);
82 auto metadatafilecontent = itemResult.data;
83 origin = itemResult.origin;
84
85 try
86 {
87 auto metadataaron = dictConverter.convert({metadatafilecontent, ""}, {});
88 metadatadict = aron::data::Dict::DynamicCastAndCheck(metadataaron);
89 }
90 catch (std::exception& ex)
91 {
92 ARMARX_ERROR << "Exception during conversion from file into json object. At entity instance=" << id().cleanID().str() << ", file=" << metadataFilename << ", error message=" << ex.what();
93 return;
94 }
95 }
96 else
97 {
98 ARMARX_WARNING << "Could not find the metadata file '" << metadataFilename
99 << "'. Continuing without metadata.";
100 }
101
102 for (const auto& [key, m] : datadict->getElements())
103 {
104 for (auto& f : processors->converters)
105 {
106 // iterate over all files and search for matching ones.
107 // We cannot simply check for the existence of a file because we do not know the
108 // mode (filename = memberName.mode.suffix)
109 for (const auto& entityInstanceKey : persistenceStrategy_->getItemKeys(id()))
110 {
111 if (simox::alg::starts_with(entityInstanceKey, key) and
112 simox::alg::ends_with(entityInstanceKey, f->suffix))
113 {
114 std::string mode = simox::alg::remove_suffix(
115 simox::alg::remove_prefix(entityInstanceKey, key), f->suffix);
116
117 auto memberfilecontent = persistenceStrategy_->retrieveItem(id(), entityInstanceKey);
118 auto memberaron = f->convert(
119 {memberfilecontent, mode},
120 armarx::aron::Path(datadict->getPath(), std::vector<std::string>{key}));
121 datadict->setElement(key, memberaron);
122 break;
123 }
124 }
125 }
126 }
127
128 from_aron(metadatadict, datadict, wmEntityInstance);
129
130 // TODO: as parameter
131 bool usePersistenceStrategyAsOrigin = true;
132
133 if (usePersistenceStrategyAsOrigin)
134 {
135 wmEntityInstance.metadata().origin = origin;
136 }
137 }
138
139 nlohmann::json
141 {
143
144 if (id().instanceIndex < 0)
145 {
147 << "During storage of segment '" << wmEntitySnapshot.id().str()
148 << "' I noticed that the corresponding LTM has no id set. "
149 << "I set the id of the LTM to the same name, however this should not happen!";
150 id().timestamp = wmEntitySnapshot.id().timestamp;
151 }
152
153 auto& dictConverter = processors->defaultObjectConverter;
154
155 ARMARX_DEBUG << "Storing entity instance id=" << id().cleanID().str();
156
157 // data
158 auto dataAron = std::make_shared<aron::data::Dict>();
159 auto metadataAron = std::make_shared<aron::data::Dict>();
160 to_aron(metadataAron, dataAron, wmEntitySnapshot);
161
162 std::shared_ptr<aron::data::Dict> source;
163
164 bool saveAndExtract =
165 false; //if true the data is saved in extracted form and in data.aron.json
166 // this is needed if several LTMs are recorded at once because otherwise the data from the data.aron.json
167 // is not there anymore to extract from
168
169 if (saveAndExtract)
170 {
171 source = dataAron->clone();
172 }
173 else
174 {
175 source = dataAron;
176 }
177
178 // check special members for special converters
179 for (auto& converter : processors->converters)
180 {
181 ARMARX_CHECK_NOT_NULL(converter);
182 ARMARX_CHECK_NOT_NULL(converter->extractor);
183 auto dataExt = converter->extractor->extract(source);
184
185 for (const auto& [memberName, var] : dataExt.extraction)
186 {
188
189 auto [memberDataVec, memberDataModeSuffix] = converter->convert(var);
190
191 std::string filename = (memberName + memberDataModeSuffix + converter->suffix);
192
193 persistenceStrategy_->storeItem(id(), filename, memberDataVec);
194 }
195 }
196
197 // convert dict and metadata
198 auto [dataVec, dataVecModeSuffix] = dictConverter.convert(dataAron);
199 auto [metadataVec, metadataVecModeSuffix] = dictConverter.convert(metadataAron);
200 ARMARX_CHECK_EMPTY(dataVecModeSuffix);
201 ARMARX_CHECK_EMPTY(metadataVecModeSuffix);
202
203 auto dataToReturn = nlohmann::json::parse(std::string(dataVec.begin(), dataVec.end()));
204
205 {
206 std::string dataFilename = (persistence::MemoryPersistenceStrategy::DATA_FILENAME + dictConverter.suffix);
207 std::string metadataFilename = (persistence::MemoryPersistenceStrategy::METADATA_FILENAME + dictConverter.suffix);
208
209 persistenceStrategy_->storeItem(id(), dataFilename, dataVec);
210 persistenceStrategy_->storeItem(id(), metadataFilename, metadataVec);
211 }
212
213 statistics.recordedData++;
214 statistics.recordedMetaData++;
215
216 return dataToReturn;
217 }
218} // namespace armarx::armem::server::ltm
#define ARMARX_CHECK_EMPTY(c)
MemoryID cleanID() const
Definition MemoryID.cpp:133
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition MemoryID.cpp:102
EntityInstanceT & addInstance(const EntityInstanceT &instance)
Add a single instance with data.
nlohmann::json _implStore(const armem::wm::EntityInstance &wmEntityInstance) override
void _implLoadAllReferences(armem::wm::EntitySnapshot &wmEntitySnapshot) const override
void _implResolve(armem::wm::EntityInstance &wmEntitySnapshot) const override
EntityInstance(const std::string &exportName, const MemoryID &memoryId, const std::shared_ptr< Processors > &filters, const std::shared_ptr< persistence::MemoryPersistenceStrategy > &persistenceStrategy)
std::shared_ptr< Processors > processors
Definition MemoryItem.h:54
Client-side working entity instance.
Client-side working memory entity snapshot.
The Path class.
Definition Path.h:36
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
void from_aron(const aron::data::DictPtr &metadata, const aron::data::DictPtr &data, wm::EntityInstance &)
convert from metadata and data aron instance
void to_aron(aron::data::DictPtr &metadata, aron::data::DictPtr &data, const wm::EntityInstance &)
convert to metadata and aron instance
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
std::string origin
Indicates the source of the instance e.g. from a specific LTM.
#define ARMARX_TRACE
Definition trace.h:77