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.rpc.dubbo;
017
018
019import io.jboot.Jboot;
020import io.jboot.app.config.JbootConfigManager;
021import io.jboot.utils.ConfigUtil;
022import io.jboot.components.rpc.JbootrpcReferenceConfig;
023import io.jboot.components.rpc.JbootrpcServiceConfig;
024import io.jboot.components.rpc.RPCUtil;
025import io.jboot.utils.StrUtil;
026import org.apache.dubbo.config.*;
027import org.apache.dubbo.config.bootstrap.DubboBootstrap;
028
029import java.util.ArrayList;
030import java.util.List;
031import java.util.Map;
032import java.util.concurrent.ConcurrentHashMap;
033
034/**
035 * @author michael yang (fuhai999@gmail.com)
036 * @Date: 2020/3/19
037 */
038class DubboUtil {
039
040    private static Map<String, ProtocolConfig> protocolConfigMap = new ConcurrentHashMap<>();
041    private static Map<String, RegistryConfig> registryConfigMap = new ConcurrentHashMap<>();
042    private static Map<String, ProviderConfig> providerConfigMap = new ConcurrentHashMap<>();
043    private static Map<String, ConsumerConfig> consumerConfigMap = new ConcurrentHashMap<>();
044
045
046    public static void stopDubbo() {
047        DubboBootstrap.getInstance().stop();
048    }
049
050    public static void initDubbo() {
051        DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance();
052
053        //application 配置
054        ApplicationConfig applicationConfig = config(ApplicationConfig.class, "jboot.rpc.dubbo.application");
055        if (StrUtil.isBlank(applicationConfig.getName())) {
056            applicationConfig.setName("jboot");
057        }
058        //默认关闭 qos
059        if (applicationConfig.getQosEnable() == null) {
060            applicationConfig.setQosEnable(false);
061        }
062
063        dubboBootstrap.application(applicationConfig);
064
065
066        //ssl 配置
067        SslConfig sslConfig = config(SslConfig.class, "jboot.rpc.dubbo.ssl");
068        dubboBootstrap.ssl(sslConfig);
069
070
071        //monitor 配置
072        MonitorConfig monitorConfig = config(MonitorConfig.class, "jboot.rpc.dubbo.monitor");
073        dubboBootstrap.monitor(monitorConfig);
074
075
076        //metrics 配置
077        MetricsConfig metricsConfig = config(MetricsConfig.class, "jboot.rpc.dubbo.metrics");
078        dubboBootstrap.metrics(metricsConfig);
079
080
081        //module 配置
082        ModuleConfig moduleConfig = config(ModuleConfig.class, "jboot.rpc.dubbo.module");
083        dubboBootstrap.module(moduleConfig);
084
085
086        //元数据 配置
087        Map<String, MetadataReportConfig> metadataReportConfigs = configs(MetadataReportConfig.class, "jboot.rpc.dubbo.metadata-report");
088        if (!metadataReportConfigs.isEmpty()) {
089            dubboBootstrap.metadataReports(toList(metadataReportConfigs));
090        }
091
092        //配置中心配置
093        Map<String, ConfigCenterConfig> configCenterConfigs = configs(ConfigCenterConfig.class, "jboot.rpc.dubbo.config-center");
094        if (!configCenterConfigs.isEmpty()) {
095            dubboBootstrap.configCenters(toList(configCenterConfigs));
096        }
097
098
099        //协议 配置
100        Map<String, ProtocolConfig> protocolConfigs = configs(ProtocolConfig.class, "jboot.rpc.dubbo.protocol");
101        if (!protocolConfigs.isEmpty()) {
102            protocolConfigMap.putAll(protocolConfigs);
103            dubboBootstrap.protocols(toList(protocolConfigs));
104        }
105
106        //服务注册中心 配置
107        Map<String, RegistryConfig> registryConfigs = configs(RegistryConfig.class, "jboot.rpc.dubbo.registry");
108        if (!registryConfigs.isEmpty()) {
109            registryConfigMap.putAll(registryConfigs);
110            dubboBootstrap.registries(toList(registryConfigs));
111        }
112        //没有配置注册中心,一般只用于希望此服务网提供直连的方式给客户端使用
113        else {
114            RegistryConfig config = new RegistryConfig();
115            config.setAddress(RegistryConfig.NO_AVAILABLE);
116            dubboBootstrap.registry(config);
117        }
118
119
120        //方法参数配置 配置
121        Map<String, ArgumentConfig> argumentConfigs = configs(ArgumentConfig.class, "jboot.rpc.dubbo.argument");
122
123
124        //方法配置 配置
125        Map<String, MethodConfig> methodConfigs = configs(MethodConfig.class, "jboot.rpc.dubbo.method");
126        for (MethodConfig methodConfig : methodConfigs.values()) {
127            Object onreturn = methodConfig.getOnreturn();
128            if (onreturn instanceof String && ((String) onreturn).contains(".")) {
129                String[] objectAndMethod = ((String) onreturn).split("\\.");
130                methodConfig.setOnreturn(Jboot.getBean(objectAndMethod[0]));
131                methodConfig.setOnreturnMethod(objectAndMethod[1]);
132            }
133
134            Object oninvoke = methodConfig.getOninvoke();
135            if (oninvoke instanceof String && ((String) oninvoke).contains(".")) {
136                String[] objectAndMethod = ((String) oninvoke).split("\\.");
137                methodConfig.setOninvoke(Jboot.getBean(objectAndMethod[0]));
138                methodConfig.setOninvokeMethod(objectAndMethod[1]);
139            }
140
141            Object onthrow = methodConfig.getOnthrow();
142            if (onthrow instanceof String && ((String) onthrow).contains(".")) {
143                String[] objectAndMethod = ((String) onthrow).split("\\.");
144                methodConfig.setOnthrow(Jboot.getBean(objectAndMethod[0]));
145                methodConfig.setOnthrowMethod(objectAndMethod[1]);
146            }
147        }
148
149        RPCUtil.setChildConfig(methodConfigs, argumentConfigs, "jboot.rpc.dubbo.method", "argument");
150
151
152        //消费者 配置
153        Map<String, ConsumerConfig> consumerConfigs = configs(ConsumerConfig.class, "jboot.rpc.dubbo.consumer");
154        RPCUtil.setChildConfig(consumerConfigs, methodConfigs, "jboot.rpc.dubbo.consumer", "method");
155//        RPCUtil.setChildConfig(consumerConfigs, protocolConfigs, "jboot.rpc.dubbo.consumer", "protocol");
156        RPCUtil.setChildConfig(consumerConfigs, registryConfigs, "jboot.rpc.dubbo.consumer", "registry");
157
158
159        if (!consumerConfigs.isEmpty()) {
160            consumerConfigMap.putAll(consumerConfigs);
161            dubboBootstrap.consumers(toList(consumerConfigs));
162        }
163
164        //服务提供者 配置
165        Map<String, ProviderConfig> providerConfigs = configs(ProviderConfig.class, "jboot.rpc.dubbo.provider");
166        RPCUtil.setChildConfig(providerConfigs, methodConfigs, "jboot.rpc.dubbo.provider", "method");
167        RPCUtil.setChildConfig(providerConfigs, protocolConfigs, "jboot.rpc.dubbo.provider", "protocol");
168        RPCUtil.setChildConfig(providerConfigs, registryConfigs, "jboot.rpc.dubbo.provider", "registry");
169
170        if (!providerConfigs.isEmpty()) {
171            providerConfigMap.putAll(providerConfigs);
172            dubboBootstrap.providers(toList(providerConfigs));
173        }
174    }
175
176
177    public static ReferenceConfig toReferenceConfig(JbootrpcReferenceConfig jbootReferenceConfig) {
178        ReferenceConfig referenceConfig = new ReferenceConfig();
179        RPCUtil.copyDeclaredFields(jbootReferenceConfig, referenceConfig);
180
181        // reference consumer
182        if (jbootReferenceConfig.getConsumer() != null) {
183            referenceConfig.setConsumer(consumerConfigMap.get(jbootReferenceConfig.getConsumer()));
184        }
185        // set default consumer
186        else {
187            for (ConsumerConfig consumerConfig : consumerConfigMap.values()) {
188                if (consumerConfig.isDefault() != null && consumerConfig.isDefault()) {
189                    referenceConfig.setConsumer(consumerConfig);
190                }
191            }
192        }
193
194
195        //service registry
196        if (StrUtil.isNotBlank(jbootReferenceConfig.getRegistry())) {
197            referenceConfig.setRegistryIds(jbootReferenceConfig.getRegistry());
198        }
199        // set default registry
200        else {
201            for (RegistryConfig registryConfig : registryConfigMap.values()) {
202                if (registryConfig.isDefault() != null && registryConfig.isDefault()) {
203                    referenceConfig.setRegistry(registryConfig);
204                }
205            }
206        }
207
208        return referenceConfig;
209    }
210
211
212    public static ServiceConfig toServiceConfig(JbootrpcServiceConfig jbootServiceConfig) {
213        ServiceConfig serviceConfig = new ServiceConfig();
214        RPCUtil.copyDeclaredFields(jbootServiceConfig, serviceConfig);
215
216        // service provider
217        if (StrUtil.isNotBlank(jbootServiceConfig.getProvider())) {
218            serviceConfig.setProviderIds(jbootServiceConfig.getProvider());
219        }
220        // set default provider
221        else {
222            for (ProviderConfig providerConfig : providerConfigMap.values()) {
223                if (providerConfig.isDefault() != null && providerConfig.isDefault()) {
224                    serviceConfig.setProvider(providerConfig);
225                }
226            }
227        }
228
229        // service protocol
230        if (StrUtil.isNotBlank(jbootServiceConfig.getProtocol())) {
231            serviceConfig.setProtocolIds(jbootServiceConfig.getProtocol());
232        }
233        // set default protocol
234        else {
235            for (ProtocolConfig protocolConfig : protocolConfigMap.values()) {
236                if (protocolConfig.isDefault() != null && protocolConfig.isDefault()) {
237                    serviceConfig.setProtocol(protocolConfig);
238                }
239            }
240        }
241
242        // service registry
243        if (StrUtil.isNotBlank(jbootServiceConfig.getRegistry())) {
244            serviceConfig.setRegistryIds(jbootServiceConfig.getRegistry());
245        }
246        // set default registry
247        else {
248            for (RegistryConfig registryConfig : registryConfigMap.values()) {
249                if (registryConfig.isDefault() != null && registryConfig.isDefault()) {
250                    serviceConfig.setRegistry(registryConfig);
251                }
252            }
253        }
254
255        return serviceConfig;
256    }
257
258    public static ConsumerConfig getConsumer(String name) {
259        return consumerConfigMap.get(name);
260    }
261
262
263    public static ProviderConfig getProvider(String name) {
264        return providerConfigMap.get(name);
265    }
266
267
268    private static <T> T config(Class<T> clazz, String prefix) {
269        return JbootConfigManager.me().get(clazz, prefix, null);
270    }
271
272
273    private static <T> Map<String, T> configs(Class<T> clazz, String prefix) {
274        Map<String, T> ret = ConfigUtil.getConfigModels(clazz, prefix);
275
276        if (ret.size() > 0 && !RPCUtil.isDefaultConfigExist(clazz, ret)) {
277            for (Map.Entry<String, T> entry : ret.entrySet()) {
278                if ("default".equals(entry.getKey())) {
279                    if (entry.getValue() instanceof ProviderConfig) {
280                        ((ProviderConfig) entry.getValue()).setDefault(true);
281                    } else if (entry.getValue() instanceof ConsumerConfig) {
282                        ((ConsumerConfig) entry.getValue()).setDefault(true);
283                    } else if (entry.getValue() instanceof ProtocolConfig) {
284                        ((ProtocolConfig) entry.getValue()).setDefault(true);
285                    } else if (entry.getValue() instanceof RegistryConfig) {
286                        ((RegistryConfig) entry.getValue()).setDefault(true);
287                    }
288                }
289            }
290        }
291        return ret;
292    }
293
294
295    private static <T> List<T> toList(Map<String, T> map) {
296        List<T> list = new ArrayList<>(map.size());
297        for (Map.Entry<String, T> entry : map.entrySet()) {
298            AbstractConfig config = (AbstractConfig) entry.getValue();
299            config.setId(entry.getKey());
300            list.add((T) config);
301        }
302        return list;
303    }
304
305
306}