Kea  1.9.9-git
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 
13 using namespace std;
14 using namespace isc::data;
15 using namespace isc::util::encode;
16 #ifndef HAVE_PRE_0_7_6_SYSREPO
17 using namespace sysrepo;
18 #endif
19 
20 namespace {
21 
22 string encode64(const string& input) {
23  vector<uint8_t> binary;
24  binary.resize(input.size());
25  memmove(&binary[0], input.c_str(), binary.size());
26  return (encodeBase64(binary));
27 }
28 
29 string decode64(const string& input) {
30  vector<uint8_t> binary;
31  decodeBase64(input, binary);
32  string result;
33  result.resize(binary.size());
34  memmove(&result[0], &binary[0], result.size());
35  return (result);
36 }
37 
38 } // end of anonymous namespace
39 
40 namespace isc {
41 namespace yang {
42 
43 TranslatorBasic::TranslatorBasic(S_Session session, const string& model)
44  : session_(session), model_(model) {
45 }
46 
48 }
49 
51 #ifndef HAVE_PRE_0_7_6_SYSREPO
52 TranslatorBasic::value(sysrepo::S_Val s_val) {
53 #else
54 TranslatorBasic::value(S_Val s_val) {
55 #endif
56  if (!s_val) {
57  isc_throw(BadValue, "value called with null");
58  }
59  switch (s_val->type()) {
60  case SR_CONTAINER_T:
61  case SR_CONTAINER_PRESENCE_T:
62  // Internal node.
63  return (ElementPtr());
64 
65  case SR_LIST_T:
66  return (Element::createList());
67 
68  case SR_STRING_T:
69  return (Element::create(string(s_val->data()->get_string())));
70 
71  case SR_BOOL_T:
72  return (Element::create(s_val->data()->get_bool() ? true : false));
73 
74  case SR_UINT8_T:
75  return (Element::create(static_cast<long long>(s_val->data()->get_uint8())));
76 
77  case SR_UINT16_T:
78  return (Element::create(static_cast<long long>(s_val->data()->get_uint16())));
79 
80  case SR_UINT32_T:
81  return (Element::create(static_cast<long long>(s_val->data()->get_uint32())));
82 
83  case SR_INT8_T:
84  return (Element::create(static_cast<long long>(s_val->data()->get_int8())));
85 
86  case SR_INT16_T:
87  return (Element::create(static_cast<long long>(s_val->data()->get_int16())));
88 
89  case SR_INT32_T:
90  return (Element::create(static_cast<long long>(s_val->data()->get_int32())));
91 
92  case SR_DECIMAL64_T:
93  return (Element::create(s_val->data()->get_decimal64()));
94 
95  case SR_IDENTITYREF_T:
96  return (Element::create(string(s_val->data()->get_identityref())));
97 
98  case SR_ENUM_T:
99  return (Element::create(string(s_val->data()->get_enum())));
100 
101  case SR_BINARY_T:
102  return (Element::create(decode64(s_val->data()->get_binary())));
103 
104  default:
106  "value called with unsupported type: " << s_val->type());
107  }
108 }
109 
111 TranslatorBasic::getItem(const string& xpath) {
112  S_Val s_val;
113  try {
114  s_val = session_->get_item(xpath.c_str());
115  } catch (const sysrepo_exception& ex) {
116  isc_throw(SysrepoError, "sysrepo error getting item at '" << xpath
117  << "': " << ex.what());
118  }
119  if (!s_val) {
120  return (ElementPtr());
121  }
122  return (value(s_val));
123 }
124 
126 TranslatorBasic::getItems(const string& xpath) {
127  S_Vals s_vals;
128  try {
129  s_vals = session_->get_items(xpath.c_str());
130  if (!s_vals) {
131  return (ElementPtr());
132  }
133  ElementPtr result = Element::createList();
134  for (size_t i = 0; i < s_vals->val_cnt(); ++i) {
135  S_Val s_val = s_vals->val(i);
136  result->add(value(s_val));
137  }
138  return (result);
139  } catch (const sysrepo_exception& ex) {
141  "sysrepo error getting item at '" << xpath
142  << "': " << ex.what());
143  }
144 }
145 
146 S_Val
148  if (!elem) {
149  isc_throw(BadValue, "value called with null");
150  }
151  S_Val s_val;
152  switch (type) {
153  case SR_CONTAINER_T:
154  case SR_CONTAINER_PRESENCE_T:
155  isc_throw(NotImplemented, "value called for a container");
156 
157  case SR_LIST_T:
158  if (elem->getType() != Element::list) {
159  isc_throw(BadValue, "value for a list called with not a list: "
160  << elem->str());
161  }
162  // Return null.
163  break;
164 
165  case SR_STRING_T:
166  case SR_IDENTITYREF_T:
167  case SR_ENUM_T:
168  if (elem->getType() != Element::string) {
170  "value for a string called with not a string: "
171  << elem->str());
172  }
173  s_val.reset(new Val(elem->stringValue().c_str(), type));
174  break;
175 
176  case SR_BOOL_T:
177  if (elem->getType() != Element::boolean) {
179  "value for a boolean called with not a boolean: "
180  << elem->str());
181  }
182  s_val.reset(new Val(elem->boolValue(), type));
183  break;
184 
185  case SR_UINT8_T:
186  if (elem->getType() != Element::integer) {
188  "value for an integer called with not an integer: "
189  << elem->str());
190  }
191 #ifdef HAVE_POST_0_7_7_SYSREPO
192  s_val.reset(new Val(static_cast<uint8_t>(elem->intValue())));
193 #else
194  s_val.reset(new Val(static_cast<uint8_t>(elem->intValue()), type));
195 #endif
196  break;
197 
198  case SR_UINT16_T:
199  if (elem->getType() != Element::integer) {
201  "value for an integer called with not an integer: "
202  << elem->str());
203  }
204 #ifdef HAVE_POST_0_7_7_SYSREPO
205  s_val.reset(new Val(static_cast<uint16_t>(elem->intValue())));
206 #else
207  s_val.reset(new Val(static_cast<uint16_t>(elem->intValue()), type));
208 #endif
209  break;
210 
211  case SR_UINT32_T:
212  if (elem->getType() != Element::integer) {
214  "value for an integer called with not an integer: "
215  << elem->str());
216  }
217 #ifdef HAVE_POST_0_7_7_SYSREPO
218  s_val.reset(new Val(static_cast<uint32_t>(elem->intValue())));
219 #else
220  s_val.reset(new Val(static_cast<uint32_t>(elem->intValue()), type));
221 #endif
222  break;
223 
224  case SR_INT8_T:
225  if (elem->getType() != Element::integer) {
227  "value for an integer called with not an integer: "
228  << elem->str());
229  }
230 #ifdef HAVE_POST_0_7_7_SYSREPO
231  s_val.reset(new Val(static_cast<int8_t>(elem->intValue())));
232 #else
233  s_val.reset(new Val(static_cast<int8_t>(elem->intValue()), type));
234 #endif
235  break;
236 
237  case SR_INT16_T:
238  if (elem->getType() != Element::integer) {
240  "value for an integer called with not an integer: "
241  << elem->str());
242  }
243 #ifdef HAVE_POST_0_7_7_SYSREPO
244  s_val.reset(new Val(static_cast<int16_t>(elem->intValue())));
245 #else
246  s_val.reset(new Val(static_cast<int16_t>(elem->intValue()), type));
247 #endif
248  break;
249 
250  case SR_INT32_T:
251  if (elem->getType() != Element::integer) {
253  "value for an integer called with not an integer: "
254  << elem->str());
255  }
256 #ifdef HAVE_POST_0_7_7_SYSREPO
257  s_val.reset(new Val(static_cast<int32_t>(elem->intValue())));
258 #else
259  s_val.reset(new Val(static_cast<int32_t>(elem->intValue()), type));
260 #endif
261  break;
262 
263  case SR_DECIMAL64_T:
264  if (elem->getType() != Element::real) {
265  isc_throw(BadValue, "value for a real called with not a real");
266  }
267  s_val.reset(new Val(elem->doubleValue()));
268  break;
269 
270  case SR_BINARY_T:
271  if (elem->getType() != Element::string) {
273  "value for a base64 called with not a string: "
274  << elem->str());
275  }
276  s_val.reset(new Val(encode64(elem->stringValue()).c_str(), type));
277  break;
278 
279  default:
281  "value called with unsupported type: " << type);
282  }
283 
284  return (s_val);
285 }
286 
287 void
288 TranslatorBasic::setItem(const string& xpath, ConstElementPtr elem,
289  sr_type_t type) {
290  S_Val s_val = value(elem, type);
291  if (!s_val && (type != SR_LIST_T)) {
292  return;
293  }
294  try {
295  session_->set_item(xpath.c_str(), s_val);
296  } catch (const sysrepo_exception& ex) {
298  "sysrepo error setting item '" << elem->str()
299  << "' at '" << xpath << "': " << ex.what());
300  }
301 }
302 
303 void
304 TranslatorBasic::delItem(const std::string& xpath) {
305  try {
306  session_->delete_item(xpath.c_str());
307  } catch (const sysrepo_exception& ex) {
309  "sysrepo error deleting item at '"
310  << xpath << "': " << ex.what());
311  }
312 }
313 
314 
315 S_Iter_Value
316 TranslatorBasic::getIter(const std::string& xpath) {
317  return (session_->get_items_iter(xpath.c_str()));
318 }
319 
320 string
321 TranslatorBasic::getNext(S_Iter_Value iter) {
322  if (!iter) {
323  isc_throw(BadValue, "getNext called with null");
324  }
325  S_Val s_val;
326  try {
327  s_val = session_->get_item_next(iter);
328  } catch (const sysrepo_exception&) {
329  // Should not happen according to the doc but still happen?
330  return ("");
331  }
332  if (!s_val) {
333  return ("");
334  }
335  return (s_val->xpath());
336 }
337 
338 }; // end of namespace isc::yang
339 }; // end of namespace isc
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:126
A generic exception that is thrown when a function is not implemented.
virtual ~TranslatorBasic()
Destructor.
Definition: translator.cc:47
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
STL namespace.
static isc::data::ElementPtr value(sysrepo::S_Val s_val)
Translate basic value from YANG to JSON.
Definition: translator.cc:52
sysrepo::S_Iter_Value getIter(const std::string &xpath)
List iterator methods keeping the session private.
Definition: translator.cc:316
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
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:288
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
std::string getNext(sysrepo::S_Iter_Value iter)
Get xpath of the next YANG list item.
Definition: translator.cc:321
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
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
void delItem(const std::string &xpath)
Delete basic value from YANG.
Definition: translator.cc:304
Defines the logger used by the top-level component of kea-dhcp-ddns.
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:111
std::string encodeBase64(const std::vector< uint8_t > &binary)
Encode binary data in the base64 format.
Definition: base_n.cc:449
sysrepo::S_Session session_
The sysrepo session.
Definition: translator.h:126