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.core.cluster.lookup;
  
  import com.alibaba.nacos.api.exception.NacosException;
  import com.alibaba.nacos.common.http.HttpRestResult;
  import com.alibaba.nacos.common.http.client.NacosRestTemplate;
  import com.alibaba.nacos.common.http.param.Header;
  import com.alibaba.nacos.common.http.param.Query;
  import com.alibaba.nacos.common.model.RestResult;
  import com.alibaba.nacos.common.utils.StringUtils;
  import com.alibaba.nacos.core.cluster.ServerMemberManager;
  import com.alibaba.nacos.core.utils.GenericType;
  import com.alibaba.nacos.core.utils.Loggers;
  import com.alibaba.nacos.sys.env.Constants;
  import com.alibaba.nacos.sys.env.EnvUtil;
  import org.junit.jupiter.api.AfterEach;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.extension.ExtendWith;
  import org.mockito.Mock;
  import org.mockito.junit.jupiter.MockitoExtension;
  import org.mockito.junit.jupiter.MockitoSettings;
  import org.mockito.quality.Strictness;
  import org.springframework.core.env.ConfigurableEnvironment;
  import org.springframework.test.util.ReflectionTestUtils;
  
  import java.lang.reflect.Type;
  import java.util.Map;
  
  import static com.alibaba.nacos.common.constant.RequestUrlConstants.HTTP_PREFIX;
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  import static org.mockito.ArgumentMatchers.any;
  import static org.mockito.ArgumentMatchers.eq;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  
  @ExtendWith(MockitoExtension.class)
  // todo remove this
  @MockitoSettings(strictness = Strictness.LENIENT)
  class AddressServerMemberLookupTest {
      
      private final GenericType<String> genericType = new GenericType<String>() {
      };
      
      @Mock
      private NacosRestTemplate restTemplate;
      
      @Mock
      private ServerMemberManager memberManager;
      
      @Mock
      private HttpRestResult<String> result;
      
      private AddressServerMemberLookup addressServerMemberLookup;
      
      private String addressUrl;
      
      private String envIdUrl;
      
      private String addressServerUrl;
      
      private String addressPort;
      
      private String domainName;
      
      @Mock
      private ConfigurableEnvironment environment;
      
      @BeforeEach
      void setUp() throws Exception {
          EnvUtil.setEnvironment(environment);
          when(environment.getProperty("maxHealthCheckFailCount", "12")).thenReturn("12");
          when(environment.getProperty("nacos.core.address-server.retry", Integer.class, 5)).thenReturn(5);
          when(environment.getProperty("address.server.domain", "jmenv.tbsite.net")).thenReturn("jmenv.tbsite.net");
          when(environment.getProperty("address.server.port", "8080")).thenReturn("8080");
          when(environment.getProperty(eq("address.server.url"), any(String.class))).thenReturn("/nacos/serverlist");
          when(environment.getProperty(Constants.WEB_CONTEXT_PATH)).thenReturn("/nacos");
          initAddressSys();
          when(restTemplate.<String>get(eq(addressServerUrl), any(Header.EMPTY.getClass()), any(Query.EMPTY.getClass()),
                  any(Type.class))).thenReturn(result);
          addressServerMemberLookup = new AddressServerMemberLookup();
          ReflectionTestUtils.setField(addressServerMemberLookup, "restTemplate", restTemplate);
          
          when(result.ok()).thenReturn(true);
          when(result.getData()).thenReturn("1.1.1.1:8848");
          addressServerMemberLookup.start();
      }
      
      @AfterEach
      void tearDown() throws NacosException {
          addressServerMemberLookup.destroy();
      }
      
      @Test
      void testMemberChange() throws Exception {
          addressServerMemberLookup.injectMemberManager(memberManager);
          verify(restTemplate).get(eq(addressServerUrl), any(Header.EMPTY.getClass()), any(Query.EMPTY.getClass()), any(Type.class));
      }
      
      @Test
      void testInfo() {
          Map<String, Object> infos = addressServerMemberLookup.info();
          assertEquals(4, infos.size());
          assertTrue(infos.containsKey("addressServerHealth"));
          assertTrue(infos.containsKey("addressServerUrl"));
          assertTrue(infos.containsKey("envIdUrl"));
          assertTrue(infos.containsKey("addressServerFailCount"));
          assertEquals(addressServerUrl, infos.get("addressServerUrl"));
          assertEquals(envIdUrl, infos.get("envIdUrl"));
      }
      
      @Test
      void testSyncFromAddressUrl() throws Exception {
          RestResult<String> result = restTemplate.get(addressServerUrl, Header.EMPTY, Query.EMPTY, genericType.getType());
          assertEquals("1.1.1.1:8848", result.getData());
      }
      
      private void initAddressSys() {
          String envDomainName = System.getenv("address_server_domain");
          if (StringUtils.isBlank(envDomainName)) {
              domainName = EnvUtil.getProperty("address.server.domain", "jmenv.tbsite.net");
          } else {
              domainName = envDomainName;
          }
          String envAddressPort = System.getenv("address_server_port");
          if (StringUtils.isBlank(envAddressPort)) {
              addressPort = EnvUtil.getProperty("address.server.port", "8080");
          } else {
              addressPort = envAddressPort;
          }
          String envAddressUrl = System.getenv("address_server_url");
          if (StringUtils.isBlank(envAddressUrl)) {
              addressUrl = EnvUtil.getProperty("address.server.url", EnvUtil.getContextPath() + "/" + "serverlist");
          } else {
              addressUrl = envAddressUrl;
          }
          addressServerUrl = HTTP_PREFIX + domainName + ":" + addressPort + addressUrl;
          envIdUrl = HTTP_PREFIX + domainName + ":" + addressPort + "/env";
          
          Loggers.CORE.info("ServerListService address-server port:" + addressPort);
          Loggers.CORE.info("ADDRESS_SERVER_URL:" + addressServerUrl);
      }
  }
  