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.common.model.RestResult;
  import com.alibaba.nacos.common.utils.StringUtils;
  import com.alibaba.nacos.config.server.constant.Constants;
  import com.alibaba.nacos.config.server.model.capacity.Capacity;
  import com.alibaba.nacos.config.server.paramcheck.ConfigDefaultHttpParamExtractor;
  import com.alibaba.nacos.config.server.service.capacity.CapacityService;
  import com.alibaba.nacos.core.controller.compatibility.Compatibility;
  import com.alibaba.nacos.core.paramcheck.ExtractorManager;
  import com.alibaba.nacos.plugin.auth.constant.ApiType;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.web.bind.annotation.GetMapping;
  import org.springframework.web.bind.annotation.PostMapping;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.RestController;
  
  import jakarta.servlet.http.HttpServletResponse;
  
  /**
   * Capacity Management.
   *
   * @author hexu.hxy
   */
  @Deprecated
  @RestController
  @RequestMapping(Constants.CAPACITY_CONTROLLER_PATH)
  @ExtractorManager.Extractor(httpExtractor = ConfigDefaultHttpParamExtractor.class)
  public class CapacityController {
      
      private static final Logger LOGGER = LoggerFactory.getLogger(CapacityController.class);
      
      private final CapacityService capacityService;
      
      private static final int STATUS200 = 200;
      
      private static final int STATUS400 = 400;
      
      private static final int STATUS500 = 500;
      
      public CapacityController(CapacityService capacityService) {
          this.capacityService = capacityService;
      }
      
      @GetMapping
      @Compatibility(apiType = ApiType.ADMIN_API, alternatives = "GET {contextPath:nacos}/v3/admin/cs/capacity")
      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<>();
              response.setStatus(STATUS400);
              restResult.setCode(STATUS400);
              restResult.setMessage("The parameter group and tenant cannot be empty at the same time");
              return restResult;
          }
          if (group == null && StringUtils.isBlank(tenant)) {
              RestResult<Capacity> restResult = new RestResult<>();
              response.setStatus(STATUS400);
              restResult.setCode(STATUS400);
              restResult.setMessage("tenant cannot be an empty string");
              return restResult;
          }
          RestResult<Capacity> restResult = new RestResult<>();
          try {
              response.setStatus(STATUS200);
              restResult.setCode(STATUS200);
              Capacity capacity = capacityService.getCapacityWithDefault(group, tenant);
              if (capacity == null) {
                  LOGGER.warn("[getCapacity] capacity not exist，need init 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(STATUS500);
              restResult.setCode(STATUS500);
              restResult.setMessage(e.getMessage());
          }
          return restResult;
      }
      
      /**
       * Modify group or capacity of tenant, and init record when capacity information are still initial.
       */
      @PostMapping
      @Compatibility(apiType = ApiType.ADMIN_API, alternatives = "POST {contextPath:nacos}/v3/admin/cs/capacity")
      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<>();
              setFailResult(response, restResult, STATUS400);
              restResult.setMessage("The parameter group and tenant cannot be empty at the same time");
              return restResult;
          }
          if (quota == null && maxSize == null && maxAggrCount == null && maxAggrSize == null) {
              RestResult<Boolean> restResult = new RestResult<>();
              setFailResult(response, restResult, STATUS400);
              restResult.setMessage(
                      "The parameters quota, maxSize, maxAggrCount, maxAggrSize cannot be empty at the same time");
              return restResult;
          }
          String targetFieldName;
          String targetFieldValue;
          if (tenant == null) {
              targetFieldName = "group";
              targetFieldValue = group;
          } else {
              targetFieldName = "tenant";
              targetFieldValue = tenant;
          }
          RestResult<Boolean> restResult = new RestResult<>();
          if (StringUtils.isBlank(targetFieldValue)) {
              setFailResult(response, restResult, STATUS400);
              restResult.setMessage(String.format("parameter %s is empty.", targetFieldName));
              return restResult;
          }
          try {
              boolean insertOrUpdateResult = capacityService
                      .insertOrUpdateCapacity(group, tenant, quota, maxSize, maxAggrCount, maxAggrSize);
              if (insertOrUpdateResult) {
                  setSuccessResult(response, restResult);
                  restResult.setMessage(
                          String.format("successfully updated the capacity information configuration of %s to %s",
                                  targetFieldName, targetFieldValue));
                  return restResult;
              }
              setFailResult(response, restResult, STATUS500);
              restResult.setMessage(
                      String.format("failed updated the capacity information configuration of %s to %s", targetFieldName,
                              targetFieldValue));
              return restResult;
          } catch (Exception e) {
              LOGGER.error("[updateCapacity] ", e);
              setFailResult(response, restResult, STATUS500);
              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(STATUS200);
          restResult.setCode(STATUS200);
          restResult.setData(true);
      }
  }
  