content: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   *
   * 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 com.alibaba.nacos.config.server.controller;
  
  import com.alibaba.nacos.config.server.constant.Constants;
  import com.alibaba.nacos.config.server.model.RestResult;
  import com.alibaba.nacos.config.server.model.capacity.Capacity;
  import com.alibaba.nacos.config.server.service.capacity.CapacityService;
  import org.apache.commons.lang3.StringUtils;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Controller;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestMethod;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.ResponseBody;
  
  import javax.servlet.http.HttpServletResponse;
  
  /**
   * Capacity Management
   *
   * @author hexu.hxy
   */
  @Controller
  @RequestMapping(Constants.CAPACITY_CONTROLLER_PATH)
  public class CapacityController {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(CapacityController.class);
  
      private final CapacityService capacityService;
  
      @Autowired
      public CapacityController(CapacityService capacityService) {
          this.capacityService = capacityService;
      }
  
      @ResponseBody
      @RequestMapping(method = RequestMethod.GET)
      public RestResult<Capacity> getCapacity(HttpServletResponse response,
                                              @RequestParam(required = false) String group,
                                              @RequestParam(required = false) String tenant) {
          if (group == null && tenant == null) {
              RestResult<Capacity> restResult = new RestResult<Capacity>();
              response.setStatus(400);
              restResult.setCode(400);
              restResult.setMessage("参数group和tenant不能同时为空");
              return restResult;
          }
          if (group == null && StringUtils.isBlank(tenant)) {
              RestResult<Capacity> restResult = new RestResult<Capacity>();
              response.setStatus(400);
              restResult.setCode(400);
              restResult.setMessage("tenant不能为空字符串");
              return restResult;
          }
          RestResult<Capacity> restResult = new RestResult<Capacity>();
          try {
              response.setStatus(200);
              restResult.setCode(200);
              Capacity capacity = capacityService.getCapacityWithDefault(group, tenant);
              if (capacity == null) {
                  LOGGER.warn("[getCapacity] capacity不存在，需初始化 group: {}, tenant: {}", group, tenant);
                  capacityService.initCapacity(group, tenant);
                  capacity = capacityService.getCapacityWithDefault(group, tenant);
              }
              if (capacity != null) {
                  restResult.setData(capacity);
              }
          } catch (Exception e) {
              LOGGER.error("[getCapacity] ", e);
              response.setStatus(500);
              restResult.setCode(500);
              restResult.setMessage(e.getMessage());
          }
          return restResult;
      }
  
      /**
       * 修改Group或租户的容量，容量信息还没有初始化的则初始化记录
       */
      @ResponseBody
      @RequestMapping(method = RequestMethod.POST)
      public RestResult<Boolean> updateCapacity(HttpServletResponse response,
                                                @RequestParam(required = false) String group,
                                                @RequestParam(required = false) String tenant,
                                                @RequestParam(required = false) Integer quota,
                                                @RequestParam(required = false) Integer maxSize,
                                                @RequestParam(required = false) Integer maxAggrCount,
                                                @RequestParam(required = false) Integer maxAggrSize) {
          if (StringUtils.isBlank(group) && StringUtils.isBlank(tenant)) {
              capacityService.initAllCapacity();
              RestResult<Boolean> restResult = new RestResult<Boolean>();
              setFailResult(response, restResult, 400);
              restResult.setMessage("参数group和tenant不能同时为空");
              return restResult;
          }
          if (quota == null && maxSize == null && maxAggrCount == null && maxAggrSize == null) {
              RestResult<Boolean> restResult = new RestResult<Boolean>();
              setFailResult(response, restResult, 400);
              restResult.setMessage("参数quota、maxSize、maxAggrCount、maxAggrSize不能同时为空");
              return restResult;
          }
          String targetFieldName;
          String targetFieldValue;
          if (tenant == null) {
              targetFieldName = "group";
              targetFieldValue = group;
          } else {
              targetFieldName = "tenant";
              targetFieldValue = tenant;
          }
          RestResult<Boolean> restResult = new RestResult<Boolean>();
          if (StringUtils.isBlank(targetFieldValue)) {
              setFailResult(response, restResult, 400);
              restResult.setMessage(String.format("参数%s为空", targetFieldName));
              return restResult;
          }
          try {
              boolean insertOrUpdateResult = capacityService.insertOrUpdateCapacity(group, tenant, quota, maxSize,
                  maxAggrCount, maxAggrSize);
              if (insertOrUpdateResult) {
                  setSuccessResult(response, restResult);
                  restResult.setMessage(String.format("成功更新%s为%s的容量信息配置", targetFieldName, targetFieldValue));
                  return restResult;
              }
              setFailResult(response, restResult, 500);
              restResult.setMessage(String.format("%s为%s的容量信息配置更新失败", targetFieldName, targetFieldValue));
              return restResult;
          } catch (Exception e) {
              LOGGER.error("[updateCapacity] ", e);
              setFailResult(response, restResult, 500);
              restResult.setMessage(e.getMessage());
              return restResult;
          }
      }
  
      private void setFailResult(HttpServletResponse response, RestResult<Boolean> restResult, int statusCode) {
          response.setStatus(statusCode);
          restResult.setCode(statusCode);
          restResult.setData(false);
      }
  
      private void setSuccessResult(HttpServletResponse response, RestResult<Boolean> restResult) {
          response.setStatus(200);
          restResult.setCode(200);
          restResult.setData(true);
      }
  }
  