Kea: translator.cc Source File

| Kea 2.2.0

translator.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2019,2021 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <yang/translator.h>
10#include <util/encode/base64.h>
11#include <cstring>
12
13using namespace std;
14using namespace isc::data;
15using namespace isc::util::encode;
16using namespace sysrepo;
17
18namespace {
19
20string encode64(const string& input) {
21 vector<uint8_t> binary;
22 binary.resize(input.size());
23 memmove(&binary[0], input.c_str(), binary.size());
24 return (encodeBase64(binary));
25}
26
27string decode64(const string& input) {
28 vector<uint8_t> binary;
29 decodeBase64(input, binary);
30 string result;
31 result.resize(binary.size());
32 memmove(&result[0], &binary[0], result.size());
33 return (result);
34}
35
36} // end of anonymous namespace
37
38namespace isc {
39namespace yang {
40
41TranslatorBasic::TranslatorBasic(S_Session session, const string& model)
42 : session_(session), model_(model) {
43}
44
45TranslatorBasic::~TranslatorBasic() {
46}
47
48 ElementPtr
49TranslatorBasic::value(sysrepo::S_Val s_val) {
50 if (!s_val) {
51 isc_throw(BadValue, "value called with null");
52 }
53 switch (s_val->type()) {
54 case SR_CONTAINER_T:
55 case SR_CONTAINER_PRESENCE_T:
56 // Internal node.
57 return (ElementPtr());
58
59 case SR_LIST_T:
60 return (Element::createList());
61
62 case SR_STRING_T:
63 return (Element::create(string(s_val->data()->get_string())));
64
65 case SR_BOOL_T:
66 return (Element::create(s_val->data()->get_bool() ? true : false));
67
68 case SR_UINT8_T:
69 return (Element::create(static_cast<long long>(s_val->data()->get_uint8())));
70
71 case SR_UINT16_T:
72 return (Element::create(static_cast<long long>(s_val->data()->get_uint16())));
73
74 case SR_UINT32_T:
75 return (Element::create(static_cast<long long>(s_val->data()->get_uint32())));
76
77 case SR_INT8_T:
78 return (Element::create(static_cast<long long>(s_val->data()->get_int8())));
79
80 case SR_INT16_T:
81 return (Element::create(static_cast<long long>(s_val->data()->get_int16())));
82
83 case SR_INT32_T:
84 return (Element::create(static_cast<long long>(s_val->data()->get_int32())));
85
86 case SR_DECIMAL64_T:
87 return (Element::create(s_val->data()->get_decimal64()));
88
89 case SR_IDENTITYREF_T:
90 return (Element::create(string(s_val->data()->get_identityref())));
91
92 case SR_ENUM_T:
93 return (Element::create(string(s_val->data()->get_enum())));
94
95 case SR_BINARY_T:
96 return (Element::create(decode64(s_val->data()->get_binary())));
97
98 default:
99 isc_throw(NotImplemented,
100 "value called with unsupported type: " << s_val->type());
101 }
102}
103
104 ElementPtr
105TranslatorBasic::getItem(const string& xpath) {
106 S_Val s_val;
107 try {
108 s_val = session_->get_item(xpath.c_str());
109 } catch (const sysrepo_exception& ex) {
110 if (std::string(ex.what()).find("Item not found") != string::npos) {
111 // The YANG configuration node was not there.
112 return nullptr;
113 }
114 isc_throw(SysrepoError, "sysrepo error getting item at '" << xpath
115 << "': " << ex.what());
116 }
117 if (!s_val) {
118 return (ElementPtr());
119 }
120 return (value(s_val));
121}
122
123 ElementPtr
124TranslatorBasic::getItems(const string& xpath) {
125 S_Vals s_vals(getValuesFromItems(xpath));
126 if (!s_vals) {
127 return (ElementPtr());
128 }
129 ElementPtr result(Element::createList());
130 try {
131 for (size_t i = 0; i < s_vals->val_cnt(); ++i) {
132 S_Val s_val = s_vals->val(i);
133 result->add(value(s_val));
134 }
135 } catch (const sysrepo_exception& ex) {
136 isc_throw(SysrepoError, "sysrepo error getting item at '"
137 << xpath << "': " << ex.what());
138 }
139 return (result);
140}
141
142S_Val
143 TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
144 if (!elem) {
145 isc_throw(BadValue, "value called with null");
146 }
147 S_Val s_val;
148 switch (type) {
149 case SR_CONTAINER_T:
150 case SR_CONTAINER_PRESENCE_T:
151 isc_throw(NotImplemented, "value called for a container");
152
153 case SR_LIST_T:
154 if (elem->getType() != Element::list) {
155 isc_throw(BadValue, "value for a list called with not a list: "
156 << elem->str());
157 }
158 // Return null.
159 break;
160
161 case SR_STRING_T:
162 case SR_IDENTITYREF_T:
163 case SR_ENUM_T:
164 if (elem->getType() != Element::string) {
165 isc_throw(BadValue,
166 "value for a string called with not a string: "
167 << elem->str());
168 }
169 s_val.reset(new Val(elem->stringValue().c_str(), type));
170 break;
171
172 case SR_BOOL_T:
173 if (elem->getType() != Element::boolean) {
174 isc_throw(BadValue,
175 "value for a boolean called with not a boolean: "
176 << elem->str());
177 }
178 s_val.reset(new Val(elem->boolValue(), type));
179 break;
180
181 case SR_UINT8_T:
182 if (elem->getType() != Element::integer) {
183 isc_throw(BadValue,
184 "value for an integer called with not an integer: "
185 << elem->str());
186 }
187 s_val.reset(new Val(elem->intValue(), type));
188 break;
189
190 case SR_UINT16_T:
191 if (elem->getType() != Element::integer) {
192 isc_throw(BadValue,
193 "value for an integer called with not an integer: "
194 << elem->str());
195 }
196 s_val.reset(new Val(elem->intValue(), type));
197 break;
198
199 case SR_UINT32_T:
200 if (elem->getType() != Element::integer) {
201 isc_throw(BadValue,
202 "value for an integer called with not an integer: "
203 << elem->str());
204 }
205 s_val.reset(new Val(elem->intValue(), type));
206 break;
207
208 case SR_INT8_T:
209 if (elem->getType() != Element::integer) {
210 isc_throw(BadValue,
211 "value for an integer called with not an integer: "
212 << elem->str());
213 }
214 s_val.reset(new Val(elem->intValue(), type));
215 break;
216
217 case SR_INT16_T:
218 if (elem->getType() != Element::integer) {
219 isc_throw(BadValue,
220 "value for an integer called with not an integer: "
221 << elem->str());
222 }
223 s_val.reset(new Val(elem->intValue(), type));
224 break;
225
226 case SR_INT32_T:
227 if (elem->getType() != Element::integer) {
228 isc_throw(BadValue,
229 "value for an integer called with not an integer: "
230 << elem->str());
231 }
232 s_val.reset(new Val(elem->intValue(), type));
233 break;
234
235 case SR_DECIMAL64_T:
236 if (elem->getType() != Element::real) {
237 isc_throw(BadValue, "value for a real called with not a real");
238 }
239 s_val.reset(new Val(elem->doubleValue()));
240 break;
241
242 case SR_BINARY_T:
243 if (elem->getType() != Element::string) {
244 isc_throw(BadValue,
245 "value for a base64 called with not a string: "
246 << elem->str());
247 }
248 s_val.reset(new Val(encode64(elem->stringValue()).c_str(), type));
249 break;
250
251 default:
252 isc_throw(NotImplemented,
253 "value called with unsupported type: " << type);
254 }
255
256 return (s_val);
257}
258
259void
260TranslatorBasic::setItem(const string& xpath, ConstElementPtr elem,
261 sr_type_t type) {
262 S_Val s_val = value(elem, type);
263 try {
264 session_->set_item(xpath.c_str(), s_val);
265 } catch (const sysrepo_exception& ex) {
266 isc_throw(SysrepoError,
267 "sysrepo error setting item '" << elem->str()
268 << "' at '" << xpath << "': " << ex.what());
269 }
270 session_->apply_changes();
271}
272
273void
274TranslatorBasic::checkAndGetLeaf(ElementPtr& storage,
275 const std::string& xpath,
276 const std::string& name) {
277 ConstElementPtr x = getItem(xpath + "/" + name);
278 if (x) {
279 storage->set(name, x);
280 }
281}
282
283 void TranslatorBasic::checkAndSetLeaf(ConstElementPtr const& from,
284 string const& xpath,
285 string const& name,
286 sr_type_t const type) {
287 ConstElementPtr const& x(from->get(name));
288 if (x) {
289 setItem(xpath + "/" + name, x, type);
290 }
291}
292
293void
294TranslatorBasic::delItem(const std::string& xpath) {
295 try {
296 session_->delete_item(xpath.c_str());
297 } catch (const sysrepo_exception& ex) {
298 if (std::string(ex.what()).find("Invalid argument") != string::npos) {
299 // The YANG configuration node was not there.
300 return;
301 }
302 isc_throw(SysrepoError,
303 "sysrepo error deleting item at '"
304 << xpath << "': " << ex.what());
305 }
306 session_->apply_changes();
307}
308
309S_Vals TranslatorBasic::getValuesFromItems(std::string const& xpath) {
310 try {
311 return session_->get_items(xpath.c_str());
312 } catch (sysrepo::sysrepo_exception const& exception) {
313 isc_throw(SysrepoError, "sysrepo error getting items: " << exception.what());
314 }
315}
316
317} // namespace yang
318} // namespace isc
base64.h
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition: exceptions/exceptions.h:132
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition: exceptions/exceptions.cc:32
isc::NotImplemented
A generic exception that is thrown when a function is not implemented.
Definition: exceptions/exceptions.h:166
isc::yang::SysrepoError
Sysrepo error.
Definition: sysrepo_error.h:16
isc::yang::TranslatorBasic::value
static isc::data::ElementPtr value(sysrepo::S_Val s_val)
Translate basic value from YANG to JSON.
Definition: translator.cc:49
isc::yang::TranslatorBasic::getItem
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:105
isc::yang::TranslatorBasic::checkAndGetLeaf
void checkAndGetLeaf(isc::data::ElementPtr &storage, const std::string &xpath, const std::string &name)
Retrieves an item and stores it in the specified storage.
Definition: translator.cc:274
isc::yang::TranslatorBasic::TranslatorBasic
TranslatorBasic(sysrepo::S_Session session, const std::string &model)
Constructor.
Definition: translator.cc:41
isc::yang::TranslatorBasic::delItem
void delItem(const std::string &xpath)
Delete basic value from YANG.
Definition: translator.cc:294
isc::yang::TranslatorBasic::setItem
void setItem(const std::string &xpath, isc::data::ConstElementPtr elem, sr_type_t type)
Translate and set basic value from JSON to YANG.
Definition: translator.cc:260
isc::yang::TranslatorBasic::getValuesFromItems
sysrepo::S_Vals getValuesFromItems(std::string const &xpath)
Get the values of all siblings at a certain xpath.
Definition: translator.cc:309
isc::yang::TranslatorBasic::session_
sysrepo::S_Session session_
The sysrepo session.
Definition: translator.h:168
isc::yang::TranslatorBasic::getItems
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:124
isc::yang::TranslatorBasic::checkAndSetLeaf
void checkAndSetLeaf(isc::data::ConstElementPtr const &from, std::string const &xpath, std::string const &name, sr_type_t const type)
Get an element from given ElementPtr node and set it in sysrepo at given xpath.
Definition: translator.cc:283
isc::yang::TranslatorBasic::~TranslatorBasic
virtual ~TranslatorBasic()
Destructor.
Definition: translator.cc:45
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:210
isc::data
Definition: base_stamped_element.cc:12
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
isc::util::encode
Definition: base32hex.h:22
isc::util::encode::decodeBase64
void decodeBase64(const std::string &input, std::vector< uint8_t > &result)
Decode a text encoded in the base64 format into the original data.
Definition: base_n.cc:454
isc::util::encode::encodeBase64
std::string encodeBase64(const std::vector< uint8_t > &binary)
Encode binary data in the base64 format.
Definition: base_n.cc:449
isc
Defines the logger used by the top-level component of kea-lfc.
Definition: agent_parser.cc:143
translator.h