User story RICPLT-2620
[ric-app/admin.git] / src / json / json_handler.cc
diff --git a/src/json/json_handler.cc b/src/json/json_handler.cc
deleted file mode 100644 (file)
index a14b341..0000000
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
-==================================================================================
-
-        Copyright (c) 2018-2019 AT&T Intellectual Property.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================================
-*/
-/*
- Author : Ashwin Sridharan
-
-  
-*/
-
-#include <json_handler.hpp>
-#include <cstdio>
-
-TrieNode::TrieNode(int val): val_type(-1){
-  _id.tag = DataContainer::Types::integer;
-  _id.value.i = val;
-}
-
-TrieNode::TrieNode( std::string val) : val_type(-1){
-  _id.tag = DataContainer::Types::str;
-  _id.value.s.assign(val);
-}
-
-void TrieNode::set_value(const char * val){
-  _val.tag = DataContainer::Types::str;
-  _val.value.s.assign(val);  
-}
-
-
-void TrieNode::set_value(bool val){
-  _val.tag = DataContainer::Types::boolean;
-  _val.value.b = val;
-  
-}
-
-void TrieNode::set_value(int val){
-  _val.tag = DataContainer::Types::integer;
-  _val.value.i = val;
-  //std::cout <<"Assigned integer " << val << std::endl;
-
-    
-}
-
-void TrieNode::set_value(unsigned int val){
-  _val.tag = DataContainer::Types::uinteger;
-  _val.value.ui = val;
-  
-}
-
-void TrieNode::set_value( long int val){
-  _val.tag = DataContainer::Types::big_integer;
-  _val.value.l = val;
-}
-
-void TrieNode::set_value(unsigned  long int val){
-  _val.tag = DataContainer::Types::ubig_integer;
-  _val.value.ul = val;
-}
-
-void TrieNode::set_value(double val){
-  _val.tag = DataContainer::Types::real;
-  _val.value.f = val;
-    
-}
-
-
-void TrieNode::set_value(std::string val){
-  _val.tag = DataContainer::Types::str;
-  _val.value.s.assign(val);
-}
-
-void TrieNode::set_value(const char * c, size_t len){
-  _val.tag = DataContainer::Types::str;
-  _val.value.s.assign(c, len);
-}
-
-void TrieNode::add_child(TrieNode * node){
-  _children.push_back(node);
-};
-
-
-
-void TrieNode::print_id(void){
-  switch(_id.tag){
-
-  case DataContainer::Types::integer :
-    std::cout <<"Type = " << _id.tag << " Value = " << _id.value.i << std::endl;
-    break;
-  case DataContainer::Types::str :
-    std::cout <<"Type = " << _id.tag << " Value = " << _id.value.s << std::endl;
-    break;
-  default:
-    std::cerr<< "Error ! ID  not set or unknown type " << _id.tag;
-  }
-};
-
-void TrieNode::print_value(void){
-  switch(_val.tag){
-
-  case DataContainer::Types::boolean :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.b << std::endl;
-    break;
-  case DataContainer::Types::integer :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.i << std::endl;
-    break;
-  case DataContainer::Types::uinteger :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.ui << std::endl;
-    break;
-  case DataContainer::Types::big_integer :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.l << std::endl;
-    break;
-  case DataContainer::Types::ubig_integer :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.ul << std::endl;
-    break;
-  case DataContainer::Types::real :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.f << std::endl;
-    break;
-  case DataContainer::Types::str :
-    std::cout <<"Type = " << _val.tag << " Value = " << _val.value.s << std::endl;
-    break;
-  default:
-    std::cerr<< "Error ! Value not set or unknown type " << _val.tag;
-  }
-};
-    
-
-jsonHandler::jsonHandler(void):_is_root(false), _is_schema(false), _is_buffer(false){
-};
-
-
-
-
-void jsonHandler::load_file(std::string input_file, std::string &  contents ){
-
-  std::FILE *fp ;
-  try{
-    fp = std::fopen(input_file.c_str(), "rb");
-  }
-  catch(std::exception &e){
-    std::string error_string = "Error opening input schema file " + input_file;
-    throw std::runtime_error(error_string);
-  } 
-  
-  if (fp){
-    std::fseek(fp, 0, SEEK_END);
-    contents.resize(std::ftell(fp));
-    std::rewind(fp);
-    std::fread(&contents[0], 1, contents.size(), fp);
-    std::fclose(fp);
-  }
-  
-  else{
-    std::string error_string = "Error opening input  file " + input_file;
-    throw std::runtime_error(error_string);
-  }
-  
-}
-
-
-
-void jsonHandler::load_schema(std::string input_file){
-
-  load_file(input_file, _contents);
-  Document _doc;
-  if (_doc.Parse(_contents.c_str()).HasParseError()){
-    std::string error_string = input_file + " is invalid JSON" ;
-    throw std::runtime_error(error_string);
-  }
-  
-  _ref_schema_doc= std::make_unique<SchemaDocument>(_doc);
-  _is_schema = true;
-  
-  
-}
-
-void  jsonHandler::load_schema(std::string input_file, TrieNode * root){
-
-  load_file(input_file, _contents);
-  std::string response;
-  Document _doc;
-  if (_doc.Parse(_contents.c_str()).HasParseError()){
-    std::string error_string = input_file + " is invalid JSON" ;
-    throw std::runtime_error(error_string);
-  }
-  
-  // Get message schema
-  bool res;
-  Value  _schema_root;
-  Value &_root = _doc;
-  res = find_member(_root,  response, root, _schema_root);
-  if (res == false){
-    throw std::runtime_error(response);
-  }
-
-  _ref_schema_doc= std::make_unique<SchemaDocument>(_schema_root);
-  _is_schema = true;
-  
-}
-
-void jsonHandler::load_buffer(std::string input_file){
-  
-  load_file(input_file, _buffer);
-  Document _doc;
-  if (_doc.Parse(_buffer.c_str()).HasParseError()){
-    std::string error_string = input_file + " is invalid JSON" ;
-    throw std::runtime_error(error_string);
-  }   
-  _is_buffer = true;
-  
-}
-
-void jsonHandler::load_buffer(std::string input_file, TrieNode * root){
-  
-  load_file(input_file, _buffer);
-  Document _doc;
-  std::string response;
-  
-  if (_doc.Parse(_buffer.c_str()).HasParseError()){
-    std::string error_string = input_file + " is invalid JSON" ;
-    throw std::runtime_error(error_string);
-  }   
-
-  bool res;
-  Value _buffer_root;
-  res = find_member(_doc, response, root, _buffer_root);
-  if(res == false){
-    throw std::runtime_error(response);
-  }
-
-  StringBuffer out_buffer;
-  Writer<StringBuffer> writer(out_buffer);
-  _buffer_root.Accept(writer);
-  _buffer.assign(out_buffer.GetString(), out_buffer.GetLength());
-  _is_buffer = true;
-}
-
-
-std::string jsonHandler::get_buffer(void){
-  std::string response;  
-  if (_is_buffer){
-    response.assign(_buffer);
-  }
-  else{
-    response = "";
-  }
-  
-  return response;
-}
-
-
-  
-
-
-
-bool jsonHandler::find_member(const std::string schema, std::string & response, TrieNode * root, Value & TargetVal){
-
-  Document doc;
-  std::string contents(schema);
-  
-  if(doc.Parse(contents.c_str()).HasParseError()){
-    response.assign("Error Parsing JSON File");
-    return false;
-  }
-
-  return find_member(doc, response, root, TargetVal);
-  return true;
-};
-
-
-bool jsonHandler::find_member(Value & doc_root, std::string & response, TrieNode * root, Value & TargetVal){
-
-  if (!root){
-    response.assign("Null Trie root node");
-    return false;
-  }
-  //std::cout <<"LOoking for schema root" << std::endl;
-
-  Value & json_node = doc_root;
-  TrieNode * trie_node = root;  
-  Value::MemberIterator itr;
-  
-  while(1){
-
-    DataContainer const * d  = trie_node->get_id();
-    if (! d){
-      response.assign("Error could not find any id for trie node ");
-      return false;
-    }
-
-    if (d->tag == DataContainer::Types::integer && json_node.IsArray()){
-      if (json_node.Size() < d->value.i){
-       response.assign("Error json array size ");
-       response +=  std::to_string(json_node.Size())  +  " is smaller than trie node index " + std::to_string( d->value.i);
-       return false;
-      }
-      
-      if (trie_node->is_child()){
-       response.assign("Error child trie points to an array ? ");
-       return false;
-      }
-
-      trie_node = trie_node->get_children()[0];
-      json_node = json_node[d->value.i];
-    }
-    else if (d->tag == DataContainer::Types::str && json_node.IsObject()){
-      
-      itr = json_node.FindMember(d->value.s.c_str());
-      if (itr == json_node.MemberEnd()){
-       response.assign("Error ! Could not find key = ");
-       response +=  d->value.s;
-       return false;
-      }
-      if (trie_node->is_child()){
-       // reached end of trie 
-       if (itr->value.IsObject()){
-         TargetVal = itr->value.GetObject();
-         //std::cout <<"Reached root = " << itr->name.GetString() << std::endl;
-       }
-       else if (itr->value.IsArray()){
-         TargetVal = itr->value.GetArray();
-       }
-       else{
-         response.assign("Error ! JSON node selected  must be object or array in current version");
-         std::cerr << response << std::endl;
-         return false;
-       }
-       break;
-      }
-      else{
-       trie_node = trie_node->get_children()[0];
-       trie_node->print_id();
-       
-       if (itr->value.IsObject()){
-         json_node = itr->value.GetObject();
-       }
-       else if (itr->value.IsArray()){
-         json_node = itr->value.GetArray();
-       }
-       else{
-         std::string error_string= " Path must be an object or array";
-         response.assign(error_string);
-         return false;
-       }
-      }
-    }
-    else{
-      std::string error_string = "Mismatch when setting root  : Trie node is of type = " + std::to_string (d->tag) + " and json node is of type = " + std::to_string(json_node.GetType());
-      response.assign(error_string);
-      return false;
-    }
-
-  }
-
-  return true;
-
-}
-
-bool jsonHandler::is_valid(const char *message, int message_length,  std::string & response){
-
-  Document doc;
-  if (! _is_schema){
-    return false;
-  }
-
-  SchemaValidator validator(*(_ref_schema_doc.get()));
-  
-  // ensure message has terminator by translating to string ?
-  std::string message_s(message, message_length);
-
-  
-  // validate json 
-  if (doc.Parse(message_s.c_str()).HasParseError()){
-    
-    // return error message
-    std::string failed_message = "\"message\": \"Invalid JSON\"";
-    response.assign( failed_message );
-    return false;
-  }
-
-  
-  // Validate against our JSON input schema
-  if (!doc.Accept(validator)){
-    
-    StringBuffer sb;
-    validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
-    std::string failed_message = std::string("\"message\": \"Schema Violation:") + std::string(sb.GetString());
-    failed_message += std::string(" Invalid keyword :") + std::string(validator.GetInvalidSchemaKeyword()) + " \"";
-    response.assign(failed_message);
-    return false;
-    
-  }
-  response.assign("SUCCESS");
-  return true;
-  
-  
-}
-
-
-
-// should be thread safe since it can be expected to be called from multiple threads
-// only static external variable referenced is the schema (which should be read-only and hence ok ?)
-
-// Returns 0 if success
-// -1 if invalid json
-// -2 if invalid schema (assuming schema provided)
-// -3 unknown key
-// -4 no buffer available
-
-int jsonHandler::get_values(const  char *message, int message_length, std::string & response, TrieNode * root, std::vector<TrieNode *> & response_list){
-  
-  Document doc;
-
-  // ensure message has terminator by translating to string ?
-  std::string message_s(message, message_length);
-  
-  // validate json 
-  if (doc.Parse(message_s.c_str()).HasParseError()){
-    
-    // return error message
-    response.assign("Invalid JSON");
-    return -1;
-  }
-  
-  // Validate against our JSON input schema
-  if ( _is_schema){
-    SchemaValidator validator(*(_ref_schema_doc.get()));
-    
-    if (!doc.Accept(validator)){
-    
-      StringBuffer sb;
-      validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
-      response = std::string("Schema Violation ") + std::string(sb.GetString()) ;
-      response  += std::string(" Invalid keyword = ") + std::string(validator.GetInvalidSchemaKeyword()) + " \"";
-      return -2;
-    }
-
-  }
-  
-  Value & doc_root = doc;
-  bool res = traverse_doc(doc_root, root, true, response, response_list);
-  if (!res){
-    return -3;
-  }
-    
-  response.assign("SUCCESS");
-  return 0;
-}
-
-
-int jsonHandler::get_values( std::string & response, TrieNode * root, std::vector<TrieNode *> & response_list){
-  int res;
-  if (_is_buffer){
-    Document _doc;
-    _doc.Parse(_buffer.c_str());
-    Value & _buffer_root = _doc;
-    
-    res = traverse_doc(_buffer_root, root, true, response,  response_list);
-    return res;
-  }
-  else{
-    response = "Error !  No buffer loaded in json object for get";
-    return -4;
-  }
-}
-
-
-// If in get mode, return all values we can get
-// If in set mode, return false if we cannot set a value 
-bool jsonHandler::traverse_doc(Value & json_node, TrieNode * trie_node, bool get, std::string & response, std::vector<TrieNode* > & response_list ){
-
-  if (!trie_node){
-    response.assign(" Null Trie node ");
-    return  false;
-  }
-
-  bool res;
-  
-  DataContainer const * d  = trie_node->get_id();
-  if (! d){
-    response.assign(" Error could not find any id for trie node");
-    return false;
-  }
-  Value::MemberIterator itr;
-  
-
-  if (d->tag == DataContainer::Types::integer && json_node.IsArray()){
-    if (json_node.Size() < d->value.i){
-      response = "Error json array size " + std::to_string( json_node.Size()) +  " is smaller than trie node index " + std::to_string( d->value.i);
-      return false;
-    }
-    
-    if (trie_node->is_child()){
-      response.assign("Error child trie points to an array ? ");
-      return false;
-    }
-    
-    for (auto & e: trie_node->get_children()){
-      res = traverse_doc(json_node[d->value.i], e, get, response, response_list);
-      if (!res && ! get){                              
-       // if not in get mode and we hit a not found
-       // don't go any further, else move to next ...
-       return res;
-      }
-    }
-  }
-  
-  else if (d->tag == DataContainer::Types::str  && json_node.IsObject()){
-    itr = json_node.FindMember(d->value.s.c_str());
-    
-    if (itr == json_node.MemberEnd()){
-      response = "Error ! Could not find key " + d->value.s;
-      return false;
-    }
-
-    if (trie_node->is_child()){
-      // end of the line : do we get or set values  ?
-      bool is_set = false;
-      if (get){
-       if (itr->value.IsBool()){
-         trie_node->set_value(itr->value.GetBool());
-         is_set = true;
-       }
-       else if (itr->value.IsInt()){
-         trie_node->set_value(itr->value.GetInt());
-         is_set = true;
-       }
-       else if(itr->value.IsUint()){
-         trie_node->set_value(static_cast<unsigned int>(itr->value.GetUint()));
-         is_set = true;
-       }
-       else if(itr->value.IsUint64()){
-         trie_node->set_value(static_cast<unsigned long int>(itr->value.GetUint64()));
-         is_set = true;
-       }
-       else if (itr->value.IsInt64()){
-         trie_node->set_value(static_cast<long int>(itr->value.GetInt64()));
-         is_set = true;
-       }
-       else if ( itr->value.IsDouble()){
-         trie_node->set_value(itr->value.GetDouble());
-         is_set = true;
-       }
-       else if ( itr->value.IsString()){
-         trie_node->set_value(itr->value.GetString(), itr->value.GetStringLength());
-         is_set = true;
-       }
-       else{
-         response =  " json node corresponding to child node key  must of type bool, int or string. Is of type = "  + std::to_string(itr->value.GetType());
-         return false;
-       }
-
-       if (is_set){
-         response_list.push_back(trie_node);
-       }
-       
-       //std::cout <<"Set value of child node with key = " << d->value.s.c_str() << " Type = " << trie_node->get_type()  << std::endl;
-       
-      }
-      else{
-       DataContainer const  * d_val = trie_node->get_value();
-       if (d_val->tag == DataContainer::Types::boolean){
-         itr->value.SetBool(d_val->value.b);
-       }
-       else if (d_val->tag == DataContainer::Types::integer){
-         itr->value.SetInt(d_val->value.i);
-
-       }
-       else if (d_val->tag == DataContainer::Types::uinteger){
-         itr->value.SetUint(d_val->value.ui);
-
-       }
-       else if (d_val->tag == DataContainer::Types::big_integer){
-         itr->value.SetInt64(d_val->value.l);
-       }
-       else if (d_val->tag == DataContainer::Types::ubig_integer){
-         itr->value.SetUint64(d_val->value.ul);
-       }
-       else if (d_val->tag == DataContainer::Types::real){
-         itr->value.SetDouble(d_val->value.f);
-       }
-       else if (d_val->tag == DataContainer::Types::str){
-         itr->value.SetString(d_val->value.s.c_str(), d_val->value.s.length());                  
-       }
-       else{
-         response = " unknown type for child node value = " + std::to_string(d_val->tag) + " cannot set json node key = " +  d->value.s;
-         return false;
-       }
-      }      
-      return true;
-    }
-    else{
-      for (auto & e: trie_node->get_children()){
-       res = traverse_doc(itr->value, e, get, response, response_list);
-       if(res == false && ! get){
-         return false;
-       }
-      }
-    }
-  }
-  else{
-    response = "Mismatch : Trie node is of type = " + std::to_string(d->tag) + " while json node is of type = "  + std::to_string( json_node.GetType());
-    return false;
-  }
-
-  return true;
-  
-}
-
-
-int jsonHandler::set_values(const char * buffer, int len, std::string & response, std::vector<TrieNode *> root_nodes){
-  Document doc;
-  std::string message_s(buffer, len);
-  
-  // validate json 
-  if (doc.Parse(message_s.c_str()).HasParseError()){  
-    // return error message
-    response.assign("Invalid JSON");
-    return -1;
-  }
-
-  
-  Value & doc_root = doc;
-  // fake list to maintain signature for re-using traverse_doc
-  // since we don't return trie nodes when setting ...
-  std::vector<TrieNode *> fake_list;
-  for(auto const & e: root_nodes){
-    bool res = traverse_doc(doc_root, e, false, response, fake_list);
-    if (!res){
-      return -3;
-    }
-  }
-  
-  StringBuffer out_buffer;
-  Writer<StringBuffer> writer(out_buffer);
-  doc_root.Accept(writer);
-  response.assign(out_buffer.GetString(), out_buffer.GetLength());
-   return 0;
- }  
-
-
-// wrapper if instead of providing buffer, we simply use stored json object and use it
-int jsonHandler::set_values(std::string & response, std::vector<TrieNode *> root_nodes){
-  if (_is_buffer){
-    std::vector<TrieNode *> fake_list;
-    Document _doc;
-    _doc.Parse(_buffer.c_str());
-    Value & _buffer_root = _doc;
-    
-    for(auto const & e: root_nodes){
-      bool res  = traverse_doc(_buffer_root, e,  false, response, fake_list);
-      if (!res){
-       return -3;
-      }
-    }
-    
-    StringBuffer out_buffer;
-    Writer<StringBuffer> writer(out_buffer);
-    _buffer_root.Accept(writer);
-    response.assign(out_buffer.GetString(), out_buffer.GetLength());
-    return 0;
-  }
-  else{
-    response = "Error ! " + std::string( __FILE__) + "," + std::to_string(__LINE__) + " :  No buffer loaded in json object to set";
-    return -1;
-  }
-  
-}