mirror of https://github.com/tikv/pd.git
206 lines
6.3 KiB
Go
206 lines
6.3 KiB
Go
// Copyright 2016 TiKV Project Authors.
|
|
//
|
|
// 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.
|
|
|
|
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/unrolled/render"
|
|
|
|
"github.com/tikv/pd/pkg/schedule/operator"
|
|
"github.com/tikv/pd/pkg/utils/apiutil"
|
|
"github.com/tikv/pd/server"
|
|
)
|
|
|
|
type operatorHandler struct {
|
|
*server.Handler
|
|
r *render.Render
|
|
}
|
|
|
|
func newOperatorHandler(handler *server.Handler, r *render.Render) *operatorHandler {
|
|
return &operatorHandler{
|
|
Handler: handler,
|
|
r: r,
|
|
}
|
|
}
|
|
|
|
// GetOperatorsByRegion gets a Region's pending operator.
|
|
// @Tags operator
|
|
// @Summary Get a Region's pending operator.
|
|
// @Param region_id path int true "A Region's Id"
|
|
// @Produce json
|
|
// @Success 200 {object} operator.OpWithStatus
|
|
// @Failure 400 {string} string "The input is invalid."
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators/{region_id} [get]
|
|
func (h *operatorHandler) GetOperatorsByRegion(w http.ResponseWriter, r *http.Request) {
|
|
id := mux.Vars(r)["region_id"]
|
|
|
|
regionID, err := strconv.ParseUint(id, 10, 64)
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
op, err := h.GetOperatorStatus(regionID)
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
h.r.JSON(w, http.StatusOK, op)
|
|
}
|
|
|
|
// GetOperators lists all pending operators.
|
|
// @Tags operator
|
|
// @Summary List pending operators.
|
|
// @Param kind query string false "Specify the operator kind." Enums(admin, leader, region)
|
|
// @Param object query bool false "Whether to return as JSON object."
|
|
// @Produce json
|
|
// @Success 200 {array} operator.Operator
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators [get]
|
|
func (h *operatorHandler) GetOperators(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
results []*operator.Operator
|
|
err error
|
|
)
|
|
|
|
kinds, ok := r.URL.Query()["kind"]
|
|
_, objectFlag := r.URL.Query()["object"]
|
|
if !ok {
|
|
results, err = h.Handler.GetOperators()
|
|
} else {
|
|
results, err = h.GetOperatorsByKinds(kinds)
|
|
}
|
|
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
if objectFlag {
|
|
objResults := make([]*operator.OpObject, len(results))
|
|
for i, op := range results {
|
|
objResults[i] = op.ToJSONObject()
|
|
}
|
|
h.r.JSON(w, http.StatusOK, objResults)
|
|
} else {
|
|
h.r.JSON(w, http.StatusOK, results)
|
|
}
|
|
}
|
|
|
|
// DeleteOperators cancels all pending operators.
|
|
// @Tags operator
|
|
// @Summary Cancel all pending operators.
|
|
// @Produce json
|
|
// @Success 200 {string} string "All pending operators are canceled."
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators [delete]
|
|
func (h *operatorHandler) DeleteOperators(w http.ResponseWriter, _ *http.Request) {
|
|
if err := h.RemoveOperators(); err != nil {
|
|
h.r.JSON(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
h.r.JSON(w, http.StatusOK, "All pending operators are canceled.")
|
|
}
|
|
|
|
// CreateOperator creates an operator.
|
|
// FIXME: details of input json body params
|
|
// @Tags operator
|
|
// @Summary Create an operator.
|
|
// @Accept json
|
|
// @Param body body object true "json params"
|
|
// @Produce json
|
|
// @Success 200 {string} string "The operator is created."
|
|
// @Failure 400 {string} string "The input is invalid."
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators [post]
|
|
func (h *operatorHandler) CreateOperator(w http.ResponseWriter, r *http.Request) {
|
|
var input map[string]any
|
|
if err := apiutil.ReadJSONRespondError(h.r, w, r.Body, &input); err != nil {
|
|
return
|
|
}
|
|
|
|
statusCode, result, err := h.HandleOperatorCreation(input)
|
|
if err != nil {
|
|
h.r.JSON(w, statusCode, err.Error())
|
|
return
|
|
}
|
|
if statusCode == http.StatusOK && result == nil {
|
|
h.r.JSON(w, http.StatusOK, "The operator is created.")
|
|
return
|
|
}
|
|
h.r.JSON(w, statusCode, result)
|
|
}
|
|
|
|
// DeleteOperatorByRegion cancels a Region's pending operator.
|
|
// @Tags operator
|
|
// @Summary Cancel a Region's pending operator.
|
|
// @Param region_id path int true "A Region's Id"
|
|
// @Produce json
|
|
// @Success 200 {string} string "The pending operator is canceled."
|
|
// @Failure 400 {string} string "The input is invalid."
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators/{region_id} [delete]
|
|
func (h *operatorHandler) DeleteOperatorByRegion(w http.ResponseWriter, r *http.Request) {
|
|
id := mux.Vars(r)["region_id"]
|
|
|
|
regionID, err := strconv.ParseUint(id, 10, 64)
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
if err = h.RemoveOperator(regionID); err != nil {
|
|
h.r.JSON(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
h.r.JSON(w, http.StatusOK, "The pending operator is canceled.")
|
|
}
|
|
|
|
// GetOperatorRecords lists the finished operators since the given timestamp in second.
|
|
// @Tags operator
|
|
// @Summary lists the finished operators since the given timestamp in second.
|
|
// @Param from query integer false "From Unix timestamp"
|
|
// @Produce json
|
|
// @Success 200 {object} []operator.OpRecord
|
|
// @Failure 400 {string} string "The request is invalid."
|
|
// @Failure 500 {string} string "PD server failed to proceed the request."
|
|
// @Router /operators/records [get]
|
|
func (h *operatorHandler) GetOperatorRecords(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
from time.Time
|
|
err error
|
|
)
|
|
if froms := r.URL.Query()["from"]; len(froms) > 0 {
|
|
from, err = apiutil.ParseTime(froms[0])
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
}
|
|
records, err := h.GetRecords(from)
|
|
if err != nil {
|
|
h.r.JSON(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
h.r.JSON(w, http.StatusOK, records)
|
|
}
|