1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 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 "cluster_config.h"
18 
19 #include <subdoc/operations.h>
20 
21 #include <cstdlib>
22 #include <stdexcept>
23 
setConfiguration(cb::const_char_buffer buffer)24 void ClusterConfiguration::setConfiguration(cb::const_char_buffer buffer) {
25     int rev = getRevisionNumber(buffer);
26     if (rev == NoConfiguration) {
27         throw std::invalid_argument(
28                 "ClusterConfiguration::setConfiguration: Failed determine map "
29                 "revision");
30     }
31 
32     std::lock_guard<std::mutex> guard(mutex);
33     revision = rev;
34     config = std::make_shared<std::string>(buffer.begin(), buffer.end());
35 }
36 
getRevisionNumber(cb::const_char_buffer buffer)37 int ClusterConfiguration::getRevisionNumber(cb::const_char_buffer buffer) {
38     Subdoc::Operation operation;
39     Subdoc::Result result;
40     operation.set_code(Subdoc::Command::GET);
41     operation.set_doc(buffer.data(), buffer.size());
42     operation.set_result_buf(&result);
43 
44     if (operation.op_exec("rev") != Subdoc::Error::SUCCESS) {
45         return NoConfiguration;
46     }
47 
48     auto loc = result.matchloc();
49     std::string value{loc.at, loc.length};
50 
51     try {
52         std::size_t count;
53         auto ret = std::stoi(value, &count);
54         if (count == loc.length) {
55             return ret;
56         }
57     } catch (const std::exception&) {
58     }
59 
60     return NoConfiguration;
61 }
62 
reset()63 void ClusterConfiguration::reset() {
64     std::lock_guard<std::mutex> guard(mutex);
65     revision = NoConfiguration;
66     config = std::make_shared<std::string>();
67 }
68