001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.components.gateway.discovery;
017
018import com.alibaba.nacos.api.exception.NacosException;
019import com.alibaba.nacos.api.naming.NamingFactory;
020import com.alibaba.nacos.api.naming.NamingService;
021import com.alibaba.nacos.api.naming.listener.NamingEvent;
022import com.alibaba.nacos.api.naming.pojo.Instance;
023import io.jboot.Jboot;
024import io.jboot.app.config.support.nacos.NacosServerConfig;
025import io.jboot.utils.StrUtil;
026
027import java.util.ArrayList;
028import java.util.List;
029import java.util.Map;
030
031public class NacosGatewayDiscovery implements GatewayDiscovery {
032
033    private GatewayDiscoveryConfig discoveryConfig;
034    private NacosServerConfig nacosServerConfig;
035    private NamingService namingService;
036
037
038    public NacosGatewayDiscovery() {
039        this.discoveryConfig = GatewayDiscoveryManager.me().getDiscoveryConfig();
040        this.nacosServerConfig = Jboot.config(NacosServerConfig.class, "jboot.gateway.discovery.nacos");
041        try {
042            this.namingService = NamingFactory.createNamingService(nacosServerConfig.toProperties());
043        } catch (NacosException e) {
044            throw new RuntimeException("Can not create Nacos NamingService for gateway discovry. ", e);
045        }
046    }
047
048    @Override
049    public void registerInstance(GatewayInstance instance) {
050        try {
051            namingService.registerInstance(instance.getServiceName(), discoveryConfig.getGroup(), gatewayInstance2NacosInstance(instance));
052        } catch (NacosException e) {
053            e.printStackTrace();
054        }
055    }
056
057    @Override
058    public void deregisterInstance(GatewayInstance instance) {
059        try {
060            namingService.deregisterInstance(instance.getServiceName(), discoveryConfig.getGroup(), gatewayInstance2NacosInstance(instance));
061        } catch (NacosException e) {
062            e.printStackTrace();
063        }
064    }
065
066
067    @Override
068    public List<GatewayInstance> getAllInstances(String serviceName) {
069        try {
070            List<Instance> nacosInstanceList = namingService.getAllInstances(serviceName, discoveryConfig.getGroup());
071            if (nacosInstanceList != null && !nacosInstanceList.isEmpty()) {
072                List<GatewayInstance> retList = new ArrayList<>();
073                for (Instance nacosInstance : nacosInstanceList) {
074                    retList.add(nacosInstance2GatewayInstance(nacosInstance));
075                }
076                return retList;
077            }
078        } catch (NacosException e) {
079            e.printStackTrace();
080        }
081        return null;
082    }
083
084
085    @Override
086    public List<GatewayInstance> selectInstances(String serviceName, boolean healthy) {
087        try {
088            List<Instance> nacosInstanceList = namingService.selectInstances(serviceName, discoveryConfig.getGroup(), healthy);
089            if (nacosInstanceList != null && !nacosInstanceList.isEmpty()) {
090                List<GatewayInstance> retList = new ArrayList<>();
091                for (Instance nacosInstance : nacosInstanceList) {
092                    retList.add(nacosInstance2GatewayInstance(nacosInstance));
093                }
094                return retList;
095            }
096        } catch (NacosException e) {
097            e.printStackTrace();
098        }
099        return null;
100    }
101
102
103    @Override
104    public void subscribe(String serviceName, GatewayDiscoveryListener listener) {
105        try {
106            namingService.subscribe(serviceName, discoveryConfig.getGroup(), event -> {
107                GatewayDiscoveryListener.EventInfo eventInfo = new GatewayDiscoveryListener.EventInfo();
108                eventInfo.setServiceName(((NamingEvent) event).getServiceName());
109                List<Instance> nacosInstanceList = ((NamingEvent) event).getInstances();
110                if (nacosInstanceList != null && !nacosInstanceList.isEmpty()) {
111                    for (Instance nacosInstance : nacosInstanceList) {
112                        GatewayInstance instance = nacosInstance2GatewayInstance(nacosInstance);
113                        instance.setServiceName(eventInfo.getServiceName());
114                        eventInfo.addInstances(instance);
115                    }
116                }
117                listener.onEvent(eventInfo);
118            });
119        } catch (NacosException e) {
120            e.printStackTrace();
121        }
122    }
123
124    private GatewayInstance nacosInstance2GatewayInstance(Instance nacosInstance) {
125        if (nacosInstance == null) {
126            return null;
127        }
128        GatewayInstance instance = new GatewayInstance();
129        instance.setHost(nacosInstance.getIp());
130        instance.setPort(nacosInstance.getPort());
131        instance.setServiceName(instance.getServiceName());
132        instance.setHealthy(nacosInstance.isHealthy());
133
134        Map<String, String> metadata = nacosInstance.getMetadata();
135        if (metadata != null && metadata.containsKey("uri")) {
136            instance.setUri(metadata.get("uri"));
137        }
138
139        return instance;
140    }
141
142    private Instance gatewayInstance2NacosInstance(GatewayInstance gatewayInstance) {
143        if (gatewayInstance == null) {
144            return null;
145        }
146        Instance instance = new Instance();
147        instance.setIp(gatewayInstance.getHost());
148        instance.setPort(gatewayInstance.getPort());
149        instance.setServiceName(instance.getServiceName());
150        instance.setHealthy(gatewayInstance.isHealthy());
151
152        if (StrUtil.isNotBlank(gatewayInstance.getUri())) {
153            instance.addMetadata("uri", gatewayInstance.getUri());
154        }
155
156        return instance;
157    }
158}