Coverage Report

Created: 2026-03-20 03:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/service/http/action/config_action.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  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,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "service/http/action/config_action.h"
19
20
#include <rapidjson/document.h>
21
#include <rapidjson/encodings.h>
22
#include <rapidjson/prettywriter.h>
23
#include <rapidjson/stringbuffer.h>
24
#include <rapidjson/writer.h>
25
26
#include <cstdint>
27
#include <map>
28
#include <ostream>
29
#include <string>
30
#include <utility>
31
#include <vector>
32
33
#include "absl/strings/substitute.h"
34
#include "common/cast_set.h"
35
#include "common/config.h"
36
#include "common/logging.h"
37
#include "common/status.h"
38
#include "service/http/http_channel.h"
39
#include "service/http/http_headers.h"
40
#include "service/http/http_request.h"
41
#include "service/http/http_status.h"
42
43
namespace doris {
44
#include "common/compile_check_begin.h"
45
46
const static std::string HEADER_JSON = "application/json";
47
const static std::string PERSIST_PARAM = "persist";
48
const std::string CONF_ITEM = "conf_item";
49
50
124
void ConfigAction::handle(HttpRequest* req) {
51
124
    if (_config_type == ConfigActionType::UPDATE_CONFIG) {
52
43
        handle_update_config(req);
53
81
    } else if (_config_type == ConfigActionType::SHOW_CONFIG) {
54
81
        handle_show_config(req);
55
81
    }
56
124
}
57
58
81
void ConfigAction::handle_show_config(HttpRequest* req) {
59
81
    std::vector<std::vector<std::string>> config_info = config::get_config_info();
60
61
81
    rapidjson::StringBuffer str_buf;
62
81
    rapidjson::Writer<rapidjson::StringBuffer> writer(str_buf);
63
64
81
    const std::string& conf_item = req->param(CONF_ITEM);
65
66
81
    writer.StartArray();
67
55.7k
    for (const auto& _config : config_info) {
68
55.7k
        if (!conf_item.empty()) {
69
4.45k
            if (_config[0] == conf_item) {
70
16
                writer.StartArray();
71
64
                for (const std::string& config_filed : _config) {
72
64
                    writer.String(config_filed.c_str());
73
64
                }
74
16
                writer.EndArray();
75
16
                break;
76
16
            }
77
51.2k
        } else {
78
51.2k
            writer.StartArray();
79
205k
            for (const std::string& config_filed : _config) {
80
205k
                writer.String(config_filed.c_str());
81
205k
            }
82
51.2k
            writer.EndArray();
83
51.2k
        }
84
55.7k
    }
85
86
81
    writer.EndArray();
87
81
    HttpChannel::send_reply(req, str_buf.GetString());
88
81
}
89
90
43
void ConfigAction::handle_update_config(HttpRequest* req) {
91
43
    LOG(INFO) << req->debug_string();
92
93
43
    Status s;
94
43
    std::string msg;
95
43
    rapidjson::Document root;
96
43
    root.SetObject();
97
43
    rapidjson::Document results;
98
43
    results.SetArray();
99
43
    if (req->params()->size() < 1) {
100
0
        s = Status::InvalidArgument("");
101
0
        msg = "Now only support to set a single config once, via 'config_name=new_value', and with "
102
0
              "an optional parameter 'persist'.";
103
43
    } else {
104
43
        bool need_persist = false;
105
43
        if (req->params()->find(PERSIST_PARAM)->second.compare("true") == 0) {
106
0
            need_persist = true;
107
0
        }
108
44
        for (const auto& [key, value] : *req->params()) {
109
44
            if (key == PERSIST_PARAM) {
110
0
                continue;
111
0
            }
112
44
            s = config::set_config(key, value, need_persist);
113
44
            if (s.ok()) {
114
43
                LOG(INFO) << "set_config " << key << "=" << value
115
43
                          << " success. persist: " << need_persist;
116
43
            } else {
117
1
                LOG(WARNING) << "set_config " << key << "=" << value << " failed";
118
1
                msg = absl::Substitute("set $0=$1 failed, reason: $2.", key, value, s.to_string());
119
1
            }
120
44
            std::string status(s.ok() ? "OK" : "BAD");
121
44
            rapidjson::Value result;
122
44
            result.SetObject();
123
44
            result.AddMember("config_name",
124
44
                             rapidjson::Value(key.c_str(), cast_set<uint32_t>(key.size()),
125
44
                                              results.GetAllocator()),
126
44
                             results.GetAllocator());
127
44
            result.AddMember("status",
128
44
                             rapidjson::Value(status.c_str(), cast_set<uint32_t>(status.size()),
129
44
                                              results.GetAllocator()),
130
44
                             results.GetAllocator());
131
44
            result.AddMember("msg",
132
44
                             rapidjson::Value(msg.c_str(), cast_set<uint32_t>(msg.size()),
133
44
                                              results.GetAllocator()),
134
44
                             results.GetAllocator());
135
44
            results.PushBack(result, results.GetAllocator());
136
44
        }
137
43
    }
138
139
43
    rapidjson::StringBuffer strbuf;
140
43
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
141
43
    results.Accept(writer);
142
143
43
    req->add_output_header(HttpHeaders::CONTENT_TYPE, HEADER_JSON.c_str());
144
43
    HttpChannel::send_reply(req, HttpStatus::OK, strbuf.GetString());
145
43
}
146
147
#include "common/compile_check_end.h"
148
} // namespace doris