1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2/* 3 * Copyright 2016 Couchbase, Inc 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17#include "config.h" 18#include "config_parse.h" 19#include "cmdline.h" 20#include "config_util.h" 21#include "settings.h" 22 23#include <sstream> 24 25/** 26 * Load the configuration file from disk and parse it to JSON 27 * 28 * @param file the name of the file to load 29 * @return A handle to a JSON representing the config file 30 * @throws std::runtime_error if an error occurs 31 */ 32static unique_cJSON_ptr load_config_file(const char* file) { 33 cJSON *sys; 34 config_error_t err = config_load_file(file, &sys); 35 36 if (err != CONFIG_SUCCESS) { 37 throw std::runtime_error(config_strerror(file, err)); 38 } 39 40 return unique_cJSON_ptr(sys); 41} 42 43 44/****************************************************************************** 45 * Public functions 46 *****************************************************************************/ 47 48void load_config_file(const char *file, Settings& settings) 49{ 50 settings.reconfigure(load_config_file(file)); 51} 52 53bool validate_proposed_config_changes(const char* new_cfg, cJSON* errors) { 54 55 unique_cJSON_ptr config(cJSON_Parse(new_cfg)); 56 if (config.get() == nullptr) { 57 cJSON_AddItemToArray(errors, cJSON_CreateString("JSON parse error")); 58 return false; 59 } 60 61 // Earlier we returned all of the errors, now I'm terminating on 62 // the first... Ideally all of the errors would be best, but 63 // the code is easier if we can use exceptions to abort the parsing 64 // when we hit an error. Given that this isn't something that the 65 // user would be calling every time I don't think it is a big problem.. 66 try { 67 Settings new_settings(config); 68 settings.updateSettings(new_settings, false); 69 return true; 70 } catch (const std::exception& exception) { 71 cJSON_AddItemToArray(errors, cJSON_CreateString(exception.what())); 72 } 73 74 return false; 75} 76 77void reload_config_file() { 78 LOG_INFO("Reloading config file {}", get_config_file()); 79 80 try { 81 Settings new_settings(load_config_file(get_config_file())); 82 settings.updateSettings(new_settings, true); 83 } catch (const std::exception& exception) { 84 LOG_WARNING( 85 "Validation failed while reloading config file '{}'. Error: {}", 86 get_config_file(), 87 exception.what()); 88 } 89} 90