content: /*
   * Copyright 1999-2020 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.test.config;
  
  import com.alibaba.nacos.Nacos;
  import com.alibaba.nacos.common.utils.JacksonUtils;
  import com.alibaba.nacos.config.server.constant.Constants;
  import com.alibaba.nacos.test.base.ConfigCleanUtils;
  import com.alibaba.nacos.test.base.HttpClient4Test;
  import com.alibaba.nacos.test.base.Params;
  import com.fasterxml.jackson.databind.JsonNode;
  import org.junit.jupiter.api.AfterAll;
  import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.MethodOrderer.MethodName;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.TestMethodOrder;
  import org.junit.jupiter.api.extension.ExtendWith;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.boot.test.web.server.LocalServerPort;
  import org.springframework.http.HttpMethod;
  import org.springframework.http.ResponseEntity;
  import org.springframework.test.context.junit.jupiter.SpringExtension;
  
  import java.net.URL;
  import java.util.Random;
  
  import static com.alibaba.nacos.test.config.ConfigAPIV2ConfigITCase.CONTEXT_PATH;
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  /**
   * Integration tests for Config API V2.
   *
   * @author karsonto
   */
  @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
  @ExtendWith(SpringExtension.class)
  @SpringBootTest(classes = Nacos.class, properties = {
          "server.servlet.context-path=" + CONTEXT_PATH}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
  @TestMethodOrder(MethodName.class)
  public class ConfigAPIV2ConfigITCase extends HttpClient4Test {
      
      public static final long TIME_OUT = 5000;
      
      public static final String CONTEXT_PATH = "/nacos";
      
      private static final String CONFIG_V2_CONTROLLER_PATH = CONTEXT_PATH + Constants.CONFIG_CONTROLLER_V2_PATH;
      
      private static final String CONTENT = randomContent();
      
      private static final String DATA_ID = "nacos.example";
      
      private static final String GROUP = "DEFAULT_GROUP";
      
      private static final String NAME_SPACE_ID = "public";
      
      @LocalServerPort
      private int port;
      
      @BeforeAll
      static void beforeClass() {
          ConfigCleanUtils.changeToNewTestNacosHome(ConfigAPIV2ConfigITCase.class.getSimpleName());
      }
      
      @AfterAll
      @BeforeAll
      static void cleanClientCache() throws Exception {
          ConfigCleanUtils.cleanClientCache();
      }
      
      /**
       * Generates random content for testing purposes.
       */
      public static String randomContent() {
          StringBuilder sb = new StringBuilder();
          Random rand = new Random();
          int temp = rand.nextInt(10) + 1;
          sb.append("contentTest");
          for (int i = 0; i < temp; i++) {
              sb.append(i);
          }
          return sb.toString();
      }
      
      @BeforeEach
      void setUp() throws Exception {
          String url = String.format("http://127.0.0.1:%d/", port);
          this.base = new URL(url);
      }
      
      @Test
      void test() throws Exception {
          publishConfig();
          Thread.sleep(TIME_OUT);
          String config = getConfig(true);
          assertEquals(CONTENT, config);
          Thread.sleep(TIME_OUT);
          deleteConfig();
          Thread.sleep(TIME_OUT);
          boolean thrown = false;
          try {
              getConfig(false);
          } catch (Exception e) {
              thrown = true;
          }
          assertTrue(thrown);
      }
      
      /**
       * Publishes a configuration.
       *
       * @throws Exception if an error occurs during the test.
       */
      public void publishConfig() throws Exception {
          ResponseEntity<String> response = request(CONFIG_V2_CONTROLLER_PATH,
                  Params.newParams().appendParam("dataId", DATA_ID).appendParam("group", GROUP)
                          .appendParam("namespaceId", NAME_SPACE_ID).appendParam("content", CONTENT).done(), String.class,
                  HttpMethod.POST);
          assertTrue(response.getStatusCode().is2xxSuccessful());
          JsonNode json = JacksonUtils.toObj(response.getBody());
          assertTrue(json.get("data").asBoolean());
      }
      
      public String getConfig(boolean ignoreStatusCode) throws Exception {
          ResponseEntity<String> response = request(CONFIG_V2_CONTROLLER_PATH,
                  Params.newParams().appendParam("dataId", DATA_ID).appendParam("group", GROUP)
                          .appendParam("namespaceId", NAME_SPACE_ID).done(), String.class, HttpMethod.GET);
          if (!ignoreStatusCode) {
              if (!response.getStatusCode().is2xxSuccessful()) {
                  throw new RuntimeException("Fail to get config");
              }
          } else {
              assertTrue(response.getStatusCode().is2xxSuccessful());
          }
          JsonNode json = JacksonUtils.toObj(response.getBody());
          return json.get("data").asText();
      }
      
      /**
       * Deletes a configuration.
       *
       * @throws Exception if an error occurs during the test.
       */
      public void deleteConfig() throws Exception {
          ResponseEntity<String> response = request(CONFIG_V2_CONTROLLER_PATH,
                  Params.newParams().appendParam("dataId", DATA_ID).appendParam("group", GROUP)
                          .appendParam("namespaceId", NAME_SPACE_ID).done(), String.class, HttpMethod.DELETE);
          assertTrue(response.getStatusCode().is2xxSuccessful());
          JsonNode json = JacksonUtils.toObj(response.getBody());
          assertTrue(json.get("data").asBoolean());
      }
  }
  