Kea  2.1.7-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 using namespace sysrepo;
17 
18 namespace {
19 
20 string 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 
27 string 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 
38 namespace isc {
39 namespace yang {
40 
41 TranslatorBasic::TranslatorBasic(S_Session session, const string& model)
42  : session_(session), model_(model) {
43 }
44 
46 }
47 
49 TranslatorBasic::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:
100  "value called with unsupported type: " << s_val->type());
101  }
102 }
103 
105 TranslatorBasic::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 
124 TranslatorBasic::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 
142 S_Val
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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:
253  "value called with unsupported type: " << type);
254  }
255 
256  return (s_val);
257 }
258 
259 void
260 TranslatorBasic::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) {
267  "sysrepo error setting item '" << elem->str()
268  << "' at '" << xpath << "': " << ex.what());
269  }
270  session_->apply_changes();
271 }
272 
273 void
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 
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 
293 void
294 TranslatorBasic::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  }
303  "sysrepo error deleting item at '"
304  << xpath << "': " << ex.what());
305  }
306  session_->apply_changes();
307 }
308 
309 S_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
sysrepo::S_Vals getValuesFromItems(std::string const &xpath)
Get the values of all siblings at a certain xpath.
Definition: translator.cc:309
isc::data::ElementPtr getItems(const std::string &xpath)
Get and translate a list of basic values from YANG to JSON.
Definition: translator.cc:124
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
A generic exception that is thrown when a function is not implemented.
virtual ~TranslatorBasic()
Destructor.
Definition: translator.cc:45
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
STL namespace.
static isc::data::ElementPtr value(sysrepo::S_Val s_val)
Translate basic value from YANG to JSON.
Definition: translator.cc:49
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
#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:260
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
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
void delItem(const std::string &xpath)
Delete basic value from YANG.
Definition: translator.cc:294
Defines the logger used by the top-level component of kea-lfc.
isc::data::ElementPtr getItem(const std::string &xpath)
Get and translate basic value from YANG to JSON.
Definition: translator.cc:105
std::string encodeBase64(const std::vector< uint8_t > &binary)
Encode binary data in the base64 format.
Definition: base_n.cc:449
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
sysrepo::S_Session session_
The sysrepo session.
Definition: translator.h:168