content: /*
   * Copyright 2013-2023 the original author or 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
   *
   *      https://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.cloud.nacos.discovery;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
  import com.alibaba.cloud.nacos.NacosServiceInstance;
  import com.alibaba.cloud.nacos.NacosServiceManager;
  import com.alibaba.nacos.api.exception.NacosException;
  import com.alibaba.nacos.api.naming.NamingService;
  import com.alibaba.nacos.api.naming.pojo.Instance;
  import com.alibaba.nacos.api.naming.pojo.ListView;
  
  import org.springframework.cloud.client.ServiceInstance;
  
  /**
   * @author <a href="mailto:echooy.mxq@gmail.com">echooymxq</a>
   * @author changjin wei(魏昌进)
   **/
  public class NacosServiceDiscovery {
  
  	private NacosDiscoveryProperties discoveryProperties;
  
  	private NacosServiceManager nacosServiceManager;
  
  	public NacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties,
  			NacosServiceManager nacosServiceManager) {
  		this.discoveryProperties = discoveryProperties;
  		this.nacosServiceManager = nacosServiceManager;
  	}
  
  	/**
  	 * Return all instances for the given service.
  	 * @param serviceId id of service
  	 * @return list of instances
  	 * @throws NacosException nacosException
  	 */
  	public List<ServiceInstance> getInstances(String serviceId) throws NacosException {
  		String group = discoveryProperties.getGroup();
  		List<Instance> instances = namingService().selectInstances(serviceId, group,
  				true);
  		return hostToServiceInstanceList(instances, serviceId);
  	}
  
  	/**
  	 * Return the names of all services.
  	 * @return list of service names
  	 * @throws NacosException nacosException
  	 */
  	public List<String> getServices() throws NacosException {
  		String group = discoveryProperties.getGroup();
  		ListView<String> services = namingService().getServicesOfServer(1,
  				Integer.MAX_VALUE, group);
  		return services.getData();
  	}
  
  	public static List<ServiceInstance> hostToServiceInstanceList(
  			List<Instance> instances, String serviceId) {
  		List<ServiceInstance> result = new ArrayList<>(instances.size());
  		for (Instance instance : instances) {
  			ServiceInstance serviceInstance = hostToServiceInstance(instance, serviceId);
  			if (serviceInstance != null) {
  				result.add(serviceInstance);
  			}
  		}
  		return result;
  	}
  
  	public static ServiceInstance hostToServiceInstance(Instance instance,
  			String serviceId) {
  		if (instance == null || !instance.isEnabled() || !instance.isHealthy()) {
  			return null;
  		}
  		NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
  		nacosServiceInstance.setHost(instance.getIp());
  		nacosServiceInstance.setPort(instance.getPort());
  		nacosServiceInstance.setServiceId(serviceId);
  		nacosServiceInstance.setInstanceId(instance.getInstanceId());
  
  		Map<String, String> metadata = new HashMap<>();
  		metadata.put("nacos.instanceId", instance.getInstanceId());
  		metadata.put("nacos.weight", instance.getWeight() + "");
  		metadata.put("nacos.healthy", instance.isHealthy() + "");
  		metadata.put("nacos.cluster", instance.getClusterName() + "");
  		if (instance.getMetadata() != null) {
  			metadata.putAll(instance.getMetadata());
  		}
  		metadata.put("nacos.ephemeral", String.valueOf(instance.isEphemeral()));
  		nacosServiceInstance.setMetadata(metadata);
  
  		if (metadata.containsKey("secure")) {
  			boolean secure = Boolean.parseBoolean(metadata.get("secure"));
  			nacosServiceInstance.setSecure(secure);
  		}
  		return nacosServiceInstance;
  	}
  
  	private NamingService namingService() {
  		return nacosServiceManager.getNamingService();
  	}
  
  }
  