diff --git a/pom.xml b/pom.xml index 30dd78f5..57652f34 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,7 @@ spring-cloud-alibaba-fescar spring-cloud-stream-binder-rocketmq spring-cloud-alibaba-nacos-config-server + spring-cloud-alibaba-dubbo spring-cloud-alicloud-context spring-cloud-alibaba-examples spring-cloud-alibaba-test @@ -110,6 +111,15 @@ + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + org.springframework.cloud spring-cloud-alibaba-dependencies diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml index 4aca2e25..9034205a 100644 --- a/spring-cloud-alibaba-dependencies/pom.xml +++ b/spring-cloud-alibaba-dependencies/pom.xml @@ -29,6 +29,9 @@ 2.16.0 4.3.1 2.1.6 + 2.6.5 + 0.2.1.RELEASE + 0.0.2 1.1.0 1.1.8 1.1.0 @@ -207,6 +210,49 @@ ${oss.version} + + + com.alibaba + dubbo-dependencies-bom + ${dubbo.version} + pom + import + + + + + com.alibaba + dubbo + ${dubbo.version} + + + org.springframework + spring-context + + + javax.servlet + servlet-api + + + log4j + log4j + + + + + + + com.alibaba.boot + dubbo-spring-boot-starter + ${dubbo-spring-boot.version} + + + + + com.alibaba + dubbo-registry-nacos + ${dubbo-registry-nacos.version} + diff --git a/spring-cloud-alibaba-dubbo/pom.xml b/spring-cloud-alibaba-dubbo/pom.xml new file mode 100644 index 00000000..94467a24 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/pom.xml @@ -0,0 +1,179 @@ + + + + spring-cloud-alibaba + org.springframework.cloud + 0.2.2.BUILD-SNAPSHOT + ../pom.xml + + 4.0.0 + + spring-cloud-alibaba-dubbo + Spring Cloud Alibaba Dubbo + + + + + + org.springframework.boot + spring-boot-actuator + true + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot + true + + + + org.springframework.boot + spring-boot-autoconfigure + true + + + + + org.springframework.cloud + spring-cloud-commons + true + + + + org.springframework.cloud + spring-cloud-context + true + + + + org.springframework.cloud + spring-cloud-alibaba-nacos-config + + + + org.springframework.cloud + spring-cloud-starter-openfeign + true + + + + + com.alibaba.boot + dubbo-spring-boot-starter + + + + com.alibaba + dubbo + + + + + io.netty + netty-all + + + + + org.jboss.resteasy + resteasy-jaxrs + + + + org.jboss.resteasy + resteasy-client + + + + org.jboss.resteasy + resteasy-netty4 + + + + javax.validation + validation-api + + + + org.jboss.resteasy + resteasy-jackson-provider + + + + org.jboss.resteasy + resteasy-jaxb-provider + + + + javax.servlet + javax.servlet-api + provided + + + + + io.github.openfeign + feign-jaxrs2 + 9.7.0 + + + + org.apache.commons + commons-lang3 + + + + + junit + junit + test + + + + org.springframework + spring-test + test + + + + org.springframework.boot + spring-boot-starter-web + test + + + + org.springframework.boot + spring-boot-test + test + + + + + org.springframework.cloud + spring-cloud-starter-alibaba-nacos-discovery + test + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java new file mode 100644 index 00000000..cd4422c7 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.autoconfigure; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; +import org.springframework.cloud.alibaba.dubbo.metadata.service.MetadataConfigService; +import org.springframework.cloud.alibaba.dubbo.metadata.service.NacosMetadataConfigService; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * Spring Boot Auto-Configuration class for Dubbo Metadata + * + * @author Mercy + */ +@Configuration +@Import(DubboServiceMetadataRepository.class) +public class DubboMetadataAutoConfiguration { + + @Bean + @ConditionalOnBean(NacosConfigProperties.class) + public MetadataConfigService metadataConfigService() { + return new NacosMetadataConfigService(); + } + +} \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java new file mode 100644 index 00000000..d37d8dc0 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboOpenFeignAutoConfiguration.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.autoconfigure; + +import feign.Contract; +import feign.Feign; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.alibaba.dubbo.metadata.resolver.FeignMetadataResolver; +import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver; +import org.springframework.cloud.alibaba.dubbo.openfeign.DubboFeignClientsConfiguration; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * Dubbo Feign Auto-{@link Configuration Configuration} + * + * @author Mercy + */ +@ConditionalOnClass(value = Feign.class) +@AutoConfigureAfter(FeignAutoConfiguration.class) +@EnableFeignClients(defaultConfiguration = DubboFeignClientsConfiguration.class) +@Configuration +public class DubboOpenFeignAutoConfiguration { + + @Value("${spring.application.name}") + private String currentApplicationName; + + @Bean + @ConditionalOnMissingBean + public MetadataResolver metadataJsonResolver(ObjectProvider contract) { + return new FeignMetadataResolver(currentApplicationName, contract); + } +} \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java new file mode 100644 index 00000000..7c7aa9fd --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboRestMetadataRegistrationAutoConfiguration.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.autoconfigure; + +import com.alibaba.dubbo.config.spring.ServiceBean; +import com.alibaba.dubbo.config.spring.context.event.ServiceBeanExportedEvent; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver; +import org.springframework.cloud.alibaba.dubbo.metadata.service.MetadataConfigService; +import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.EventListener; + +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * The Auto-Configuration class for Dubbo REST metadata registration, + * REST metadata that is a part of {@link Registration#getMetadata() Spring Cloud service instances' metadata} + * will be registered Spring Cloud registry. + * + * @author Mercy + */ +@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) +@ConditionalOnMissingBean(value = { + MetadataResolver.class, + MetadataConfigService.class +}) +@AutoConfigureAfter(value = {DubboMetadataAutoConfiguration.class}) +@Configuration +public class DubboRestMetadataRegistrationAutoConfiguration { + + /** + * A Map to store REST metadata temporary, its' key is the special service name for a Dubbo service, + * the value is a JSON content of JAX-RS or Spring MVC REST metadata from the annotated methods. + */ + private final Set serviceRestMetadata = new LinkedHashSet<>(); + + @Autowired + private MetadataResolver metadataResolver; + + @Autowired + private MetadataConfigService metadataConfigService; + + @EventListener(ServiceBeanExportedEvent.class) + public void recordRestMetadata(ServiceBeanExportedEvent event) throws JsonProcessingException { + ServiceBean serviceBean = event.getServiceBean(); + serviceRestMetadata.addAll(metadataResolver.resolveServiceRestMetadata(serviceBean)); + } + + /** + * Pre-handle Spring Cloud application service registered: + *

+ * Put restMetadata with the JSON format into + * {@link Registration#getMetadata() service instances' metadata} + *

+ * + * @param event {@link InstancePreRegisteredEvent} instance + */ + @EventListener(InstancePreRegisteredEvent.class) + public void registerRestMetadata(InstancePreRegisteredEvent event) throws Exception { + Registration registration = event.getRegistration(); + metadataConfigService.publishServiceRestMetadata(registration.getServiceId(), serviceRestMetadata); + } + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/context/DubboServiceRegistrationApplicationContextInitializer.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/context/DubboServiceRegistrationApplicationContextInitializer.java new file mode 100644 index 00000000..f1283e91 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/context/DubboServiceRegistrationApplicationContextInitializer.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.context; + +import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistryFactory; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * The Dubbo services will be registered as the specified Spring cloud applications that will not be considered + * normal ones, but only are used to Dubbo's service discovery even if it is based on Spring Cloud Commons abstraction. + * However, current application will be registered by other DiscoveryClientAutoConfiguration. + * + * @author Mercy + */ +public class DubboServiceRegistrationApplicationContextInitializer implements + ApplicationContextInitializer { + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + // Set ApplicationContext into SpringCloudRegistryFactory before Dubbo Service Register + SpringCloudRegistryFactory.setApplicationContext(applicationContext); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodMetadata.java new file mode 100644 index 00000000..18abf0e9 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodMetadata.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.commons.lang3.ClassUtils; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * {@link Method} Metadata + * + * @author Mercy + */ +public class MethodMetadata { + + private String name; + + private String returnType; + + private List params; + + @JsonIgnore + private Method method; + + public MethodMetadata() { + this.params = new LinkedList<>(); + } + + public MethodMetadata(Method method) { + this.name = method.getName(); + this.returnType = ClassUtils.getName(method.getReturnType()); + this.params = initParameters(method); + this.method = method; + } + + private List initParameters(Method method) { + int parameterCount = method.getParameterCount(); + if (parameterCount < 1) { + return Collections.emptyList(); + } + List params = new ArrayList<>(parameterCount); + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameterCount; i++) { + Parameter parameter = parameters[i]; + MethodParameterMetadata param = toMethodParameterMetadata(i, parameter); + params.add(param); + } + return params; + } + + private MethodParameterMetadata toMethodParameterMetadata(int index, Parameter parameter) { + MethodParameterMetadata metadata = new MethodParameterMetadata(); + metadata.setIndex(index); + metadata.setName(parameter.getName()); + metadata.setType(parameter.getType().getTypeName()); + return metadata; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getReturnType() { + return returnType; + } + + public void setReturnType(String returnType) { + this.returnType = returnType; + } + + public List getParams() { + return params; + } + + public void setParams(List params) { + this.params = params; + } + + public Method getMethod() { + return method; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MethodMetadata that = (MethodMetadata) o; + return Objects.equals(name, that.name) && + Objects.equals(returnType, that.returnType) && + Objects.equals(params, that.params); + } + + @Override + public int hashCode() { + return Objects.hash(name, returnType, params); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodParameterMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodParameterMetadata.java new file mode 100644 index 00000000..fbcaad00 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/MethodParameterMetadata.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata; + +import java.lang.reflect.Method; +import java.util.Objects; + +/** + * {@link Method} Parameter Metadata + * + * @author Mercy + */ +public class MethodParameterMetadata { + + private int index; + + private String name; + + private String type; + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MethodParameterMetadata that = (MethodParameterMetadata) o; + return index == that.index && + Objects.equals(name, that.name) && + Objects.equals(type, that.type); + } + + @Override + public int hashCode() { + return Objects.hash(index, name, type); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java new file mode 100644 index 00000000..ae3d10dc --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata; + +import feign.RequestTemplate; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +/** + * Request Metadata + * + * @author Mercy + */ +public class RequestMetadata { + + private String method; + + private String url; + + private Map> queries; + + private Map> headers; + + public RequestMetadata() { + } + + public RequestMetadata(RequestTemplate requestTemplate) { + this.method = requestTemplate.method(); + this.url = requestTemplate.url(); + this.queries = requestTemplate.queries(); + this.headers = requestTemplate.headers(); + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Map> getHeaders() { + return headers; + } + + public void setHeaders(Map> headers) { + this.headers = headers; + } + + public Map> getQueries() { + return queries; + } + + public void setQueries(Map> queries) { + this.queries = queries; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RequestMetadata that = (RequestMetadata) o; + return Objects.equals(method, that.method) && + Objects.equals(url, that.url) && + Objects.equals(queries, that.queries) && + Objects.equals(headers, that.headers); + } + + @Override + public int hashCode() { + return Objects.hash(method, url, queries, headers); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RestMethodMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RestMethodMetadata.java new file mode 100644 index 00000000..5024fefa --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RestMethodMetadata.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +/** + * Method Request Metadata + */ +public class RestMethodMetadata { + + private MethodMetadata method; + + private RequestMetadata request; + + private Map> indexToName; + + public MethodMetadata getMethod() { + return method; + } + + public void setMethod(MethodMetadata method) { + this.method = method; + } + + public RequestMetadata getRequest() { + return request; + } + + public void setRequest(RequestMetadata request) { + this.request = request; + } + + public Map> getIndexToName() { + return indexToName; + } + + public void setIndexToName(Map> indexToName) { + this.indexToName = indexToName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RestMethodMetadata that = (RestMethodMetadata) o; + return Objects.equals(method, that.method) && + Objects.equals(request, that.request) && + Objects.equals(indexToName, that.indexToName); + } + + @Override + public int hashCode() { + return Objects.hash(method, request, indexToName); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java new file mode 100644 index 00000000..d5ba11f4 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/ServiceRestMetadata.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata; + +import java.util.Set; + +/** + * Service Rest Metadata + * + * @author Mercy + * @see RestMethodMetadata + */ +public class ServiceRestMetadata { + + private String name; + + private Set meta; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getMeta() { + return meta; + } + + public void setMeta(Set meta) { + this.meta = meta; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServiceRestMetadata that = (ServiceRestMetadata) o; + + if (name != null ? !name.equals(that.name) : that.name != null) return false; + return meta != null ? meta.equals(that.meta) : that.meta == null; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (meta != null ? meta.hashCode() : 0); + return result; + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/repository/DubboServiceMetadataRepository.java new file mode 100644 index 00000000..57a0a133 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/repository/DubboServiceMetadataRepository.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata.repository; + +import com.alibaba.dubbo.config.spring.ReferenceBean; +import com.alibaba.dubbo.rpc.service.GenericService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.service.MetadataConfigService; +import org.springframework.stereotype.Repository; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments; +import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion; + +/** + * Dubbo Service Metadata {@link Repository} + * + * @author Mercy + */ +@Repository +public class DubboServiceMetadataRepository { + + /** + * Key is application name + * Value is Map + */ + private Map> genericServicesRepository = new HashMap<>(); + + private Map> methodMetadataRepository = new HashMap<>(); + + @Autowired + private MetadataConfigService metadataConfigService; + + @Value("${dubbo.target.protocol:dubbo}") + private String targetProtocol; + + @Value("${dubbo.target.cluster:failover}") + private String targetCluster; + + public void updateMetadata(String serviceName) { + + Map genericServicesMap = genericServicesRepository.computeIfAbsent(serviceName, k -> new HashMap<>()); + + Map methodMetadataMap = methodMetadataRepository.computeIfAbsent(serviceName, k -> new HashMap<>()); + + Set serviceRestMetadataSet = metadataConfigService.getServiceRestMetadata(serviceName); + + for (ServiceRestMetadata serviceRestMetadata : serviceRestMetadataSet) { + + ReferenceBean referenceBean = adaptReferenceBean(serviceRestMetadata); + + serviceRestMetadata.getMeta().forEach(restMethodMetadata -> { + RequestMetadata requestMetadata = restMethodMetadata.getRequest(); + genericServicesMap.put(requestMetadata, referenceBean.get()); + methodMetadataMap.put(requestMetadata, restMethodMetadata.getMethod()); + }); + } + } + + public GenericService getGenericService(String serviceName, RequestMetadata requestMetadata) { + return getGenericServicesMap(serviceName).get(requestMetadata); + } + + public MethodMetadata getMethodMetadata(String serviceName, RequestMetadata requestMetadata) { + return getMethodMetadataMap(serviceName).get(requestMetadata); + } + + private ReferenceBean adaptReferenceBean(ServiceRestMetadata serviceRestMetadata) { + String dubboServiceName = serviceRestMetadata.getName(); + String[] segments = getServiceSegments(dubboServiceName); + String interfaceName = getServiceInterface(segments); + String version = getServiceVersion(segments); + String group = getServiceGroup(segments); + + ReferenceBean referenceBean = new ReferenceBean(); + referenceBean.setGeneric(true); + referenceBean.setInterface(interfaceName); + referenceBean.setVersion(version); + referenceBean.setGroup(group); + referenceBean.setProtocol(targetProtocol); + referenceBean.setCluster(targetCluster); + + return referenceBean; + } + + private Map getGenericServicesMap(String serviceName) { + return genericServicesRepository.getOrDefault(serviceName, Collections.emptyMap()); + } + + private Map getMethodMetadataMap(String serviceName) { + return methodMetadataRepository.getOrDefault(serviceName, Collections.emptyMap()); + } + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/FeignMetadataResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/FeignMetadataResolver.java new file mode 100644 index 00000000..e7f80dd4 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/FeignMetadataResolver.java @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata.resolver; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.config.spring.ServiceBean; +import feign.Contract; +import feign.Feign; +import feign.MethodMetadata; +import feign.Util; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.SmartInitializingSingleton; +import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; +import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry; +import org.springframework.util.ClassUtils; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * The metadata resolver for {@link Feign} + * + * @author Mercy + */ +public class FeignMetadataResolver implements BeanClassLoaderAware, SmartInitializingSingleton, MetadataResolver { + + private static final String[] CONTRACT_CLASS_NAMES = { + "feign.jaxrs2.JAXRS2Contract", + "org.springframework.cloud.openfeign.support.SpringMvcContract", + }; + + private final String currentApplicationName; + + private final ObjectProvider contract; + + private ClassLoader classLoader; + + /** + * Feign Contracts + */ + private Collection contracts; + + public FeignMetadataResolver(String currentApplicationName, ObjectProvider contract) { + this.currentApplicationName = currentApplicationName; + this.contract = contract; + } + + @Override + public void afterSingletonsInstantiated() { + + LinkedList contracts = new LinkedList<>(); + + // Add injected Contract if available, for example SpringMvcContract Bean under Spring Cloud Open Feign + contract.ifAvailable(contracts::add); + + Stream.of(CONTRACT_CLASS_NAMES) + .filter(this::isClassPresent) // filter the existed classes + .map(this::loadContractClass) // load Contract Class + .map(this::createContract) // create instance by the specified class + .forEach(contracts::add); // add the Contract instance into contracts + + this.contracts = Collections.unmodifiableCollection(contracts); + } + + private Contract createContract(Class contractClassName) { + return (Contract) BeanUtils.instantiateClass(contractClassName); + } + + private Class loadContractClass(String contractClassName) { + return ClassUtils.resolveClassName(contractClassName, classLoader); + } + + private boolean isClassPresent(String className) { + return ClassUtils.isPresent(className, classLoader); + } + + @Override + public Set resolveServiceRestMetadata(ServiceBean serviceBean) { + + Object bean = serviceBean.getRef(); + + Class beanType = bean.getClass(); + + Set serviceRestMetadata = new LinkedHashSet<>(); + + Set methodRestMetadata = resolveMethodRestMetadata(beanType); + + List urls = serviceBean.getExportedUrls(); + + urls.stream() + .map(SpringCloudRegistry::getServiceName) + .forEach(serviceName -> { + ServiceRestMetadata metadata = new ServiceRestMetadata(); + metadata.setName(serviceName); + metadata.setMeta(methodRestMetadata); + serviceRestMetadata.add(metadata); + }); + + return serviceRestMetadata; + } + + @Override + public Set resolveMethodRestMetadata(Class targetType) { + List feignContractMethods = selectFeignContractMethods(targetType); + return contracts.stream() + .map(contract -> contract.parseAndValidatateMetadata(targetType)) + .flatMap(v -> v.stream()) + .map(methodMetadata -> resolveMethodRestMetadata(methodMetadata, targetType, feignContractMethods)) + .collect(Collectors.toSet()); + } + + /** + * Select feign contract methods + *

+ * extract some code from {@link Contract.BaseContract#parseAndValidatateMetadata(java.lang.Class)} + * + * @param targetType + * @return non-null + */ + private List selectFeignContractMethods(Class targetType) { + List methods = new LinkedList<>(); + for (Method method : targetType.getMethods()) { + if (method.getDeclaringClass() == Object.class || + (method.getModifiers() & Modifier.STATIC) != 0 || + Util.isDefault(method)) { + continue; + } + methods.add(method); + } + return methods; + } + + protected RestMethodMetadata resolveMethodRestMetadata(MethodMetadata methodMetadata, Class targetType, + List feignContractMethods) { + String configKey = methodMetadata.configKey(); + Method feignContractMethod = getMatchedFeignContractMethod(targetType, feignContractMethods, configKey); + + RestMethodMetadata metadata = new RestMethodMetadata(); + + metadata.setRequest(new RequestMetadata(methodMetadata.template())); + metadata.setMethod(new org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata(feignContractMethod)); + metadata.setIndexToName(methodMetadata.indexToName()); + + return metadata; + } + + private Method getMatchedFeignContractMethod(Class targetType, List methods, String expectedConfigKey) { + Method matchedMethod = null; + for (Method method : methods) { + String configKey = Feign.configKey(targetType, method); + if (expectedConfigKey.equals(configKey)) { + matchedMethod = method; + break; + } + } + return matchedMethod; + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + +} \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/MetadataResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/MetadataResolver.java new file mode 100644 index 00000000..4956e387 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/resolver/MetadataResolver.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata.resolver; + +import com.alibaba.dubbo.config.spring.ServiceBean; +import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; + +import java.util.Set; + +/** + * The REST metadata resolver + * + * @author Mercy + */ +public interface MetadataResolver { + + /** + * Resolve the {@link ServiceRestMetadata} {@link Set set} from {@link ServiceBean} + * + * @param serviceBean {@link ServiceBean} + * @return non-null {@link Set} + */ + Set resolveServiceRestMetadata(ServiceBean serviceBean); + + /** + * Resolve {@link RestMethodMetadata} {@link Set set} from {@link Class target type} + * + * @param targetType {@link Class target type} + * @return non-null {@link Set} + */ + Set resolveMethodRestMetadata(Class targetType); +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/MetadataConfigService.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/MetadataConfigService.java new file mode 100644 index 00000000..28b7a373 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/MetadataConfigService.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata.service; + +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; + +import java.util.Set; + +/** + * Config Service for Metadata + * + * @author Mercy + */ +public interface MetadataConfigService { + + void publishServiceRestMetadata(String serviceName, Set serviceRestMetadata); + + Set getServiceRestMetadata(String serviceName); +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/NacosMetadataConfigService.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/NacosMetadataConfigService.java new file mode 100644 index 00000000..93ce9281 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/service/NacosMetadataConfigService.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.metadata.service; + +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata; +import org.springframework.cloud.alibaba.nacos.NacosConfigProperties; + +import javax.annotation.PostConstruct; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP; + +/** + * Nacos {@link MetadataConfigService} + * + * @author Mercy + */ +public class NacosMetadataConfigService implements MetadataConfigService { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + private NacosConfigProperties nacosConfigProperties; + + private ConfigService configService; + + @PostConstruct + public void init() { + this.configService = nacosConfigProperties.configServiceInstance(); + this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + } + + /** + * Get the data Id of service rest metadata + */ + private static String getServiceRestMetadataDataId(String serviceName) { + return "metadata:rest:" + serviceName + ".json"; + } + + @Override + public void publishServiceRestMetadata(String serviceName, Set serviceRestMetadata) { + String dataId = getServiceRestMetadataDataId(serviceName); + String json = writeValueAsString(serviceRestMetadata); + try { + configService.publishConfig(dataId, DEFAULT_GROUP, json); + } catch (NacosException e) { + throw new RuntimeException(e); + } + } + + @Override + public Set getServiceRestMetadata(String serviceName) { + Set metadata = Collections.emptySet(); + String dataId = getServiceRestMetadataDataId(serviceName); + try { + String json = configService.getConfig(dataId, DEFAULT_GROUP, 1000 * 3); + metadata = objectMapper.readValue(json, + TypeFactory.defaultInstance().constructCollectionType(LinkedHashSet.class, ServiceRestMetadata.class)); + } catch (Exception e) { + throw new RuntimeException(e); + } + return metadata; + } + + private String writeValueAsString(Object object) { + String content = null; + try { + content = objectMapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException(e); + } + return content; + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboFeignClientsConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboFeignClientsConfiguration.java new file mode 100644 index 00000000..0c4d7400 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboFeignClientsConfiguration.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.openfeign; + +import feign.Contract; +import feign.Feign; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration; +import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.FeignClientsConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +/** + * Dubbo {@link Configuration} for {@link FeignClient FeignClients} + * + * @author Mercy + * @see DubboOpenFeignAutoConfiguration + * @see org.springframework.cloud.openfeign.FeignContext#setConfigurations(List) + * @see FeignClientsConfiguration + */ +@Configuration +public class DubboFeignClientsConfiguration { + + @Autowired + private Contract contract; + + @Autowired + private DubboServiceMetadataRepository dubboServiceRepository; + + @Bean + public BeanPostProcessor beanPostProcessor() { + return new BeanPostProcessor() { + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Feign.Builder) { + Feign.Builder builder = (Feign.Builder) bean; + builder.invocationHandlerFactory(new DubboInvocationHandlerFactory(contract, dubboServiceRepository)); + } + return bean; + } + }; + } + + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java new file mode 100644 index 00000000..622ae340 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandler.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.openfeign; + +import com.alibaba.dubbo.rpc.service.GenericService; +import org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.MethodParameterMetadata; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Dubbo {@link GenericService} for {@link InvocationHandler} + * + * @author Mercy + */ +public class DubboInvocationHandler implements InvocationHandler { + + private final Map genericServicesMap; + + private final Map methodMetadata; + + private final InvocationHandler defaultInvocationHandler; + + public DubboInvocationHandler(Map genericServicesMap, + Map methodMetadata, + InvocationHandler defaultInvocationHandler) { + this.genericServicesMap = genericServicesMap; + this.methodMetadata = methodMetadata; + this.defaultInvocationHandler = defaultInvocationHandler; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + GenericService genericService = genericServicesMap.get(method); + + MethodMetadata methodMetadata = this.methodMetadata.get(method); + + if (genericService == null || methodMetadata == null) { + return defaultInvocationHandler.invoke(proxy, method, args); + } + + String methodName = methodMetadata.getName(); + + String[] parameterTypes = methodMetadata + .getParams() + .stream() + .map(MethodParameterMetadata::getType) + .toArray(String[]::new); + + return genericService.$invoke(methodName, parameterTypes, args); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandlerFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandlerFactory.java new file mode 100644 index 00000000..4fd67f40 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/DubboInvocationHandlerFactory.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.openfeign; + +import com.alibaba.dubbo.rpc.service.GenericService; +import feign.Contract; +import feign.InvocationHandlerFactory; +import feign.MethodMetadata; +import feign.Target; +import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static feign.Feign.configKey; + +/** + * Dubbo {@link InvocationHandlerFactory} + * + * @author Mercy + */ +public class DubboInvocationHandlerFactory implements InvocationHandlerFactory { + + private final static InvocationHandlerFactory DEFAULT_INVOCATION_HANDLER_FACTORY = + new InvocationHandlerFactory.Default(); + + private final Contract contract; + + private final DubboServiceMetadataRepository dubboServiceRepository; + + public DubboInvocationHandlerFactory(Contract contract, DubboServiceMetadataRepository dubboServiceRepository) { + this.contract = contract; + this.dubboServiceRepository = dubboServiceRepository; + } + + @Override + public InvocationHandler create(Target target, Map dispatch) { + // The target class annotated @FeignClient + Class targetType = target.type(); + // Resolve metadata from current @FeignClient type + Map methodRequestMetadataMap = resolveMethodRequestMetadataMap(targetType, dispatch.keySet()); + // @FeignClient specifies the service name + String serviceName = target.name(); + // Update specified metadata + dubboServiceRepository.updateMetadata(serviceName); + + Map genericServicesMap = new HashMap<>(); + + Map methodMetadataMap = new HashMap<>(); + + methodRequestMetadataMap.forEach((method, requestMetadata) -> { + GenericService genericService = dubboServiceRepository.getGenericService(serviceName, requestMetadata); + org.springframework.cloud.alibaba.dubbo.metadata.MethodMetadata methodMetadata = + dubboServiceRepository.getMethodMetadata(serviceName, requestMetadata); + genericServicesMap.put(method, genericService); + methodMetadataMap.put(method, methodMetadata); + }); + + InvocationHandler defaultInvocationHandler = DEFAULT_INVOCATION_HANDLER_FACTORY.create(target, dispatch); + + DubboInvocationHandler invocationHandler = new DubboInvocationHandler(genericServicesMap, methodMetadataMap, + defaultInvocationHandler); + + return invocationHandler; + } + + private Map resolveMethodRequestMetadataMap(Class targetType, Set methods) { + Map requestMetadataMap = resolveRequestMetadataMap(targetType); + return methods.stream().collect(Collectors.toMap(method -> method, method -> + requestMetadataMap.get(configKey(targetType, method)) + )); + } + + private Map resolveRequestMetadataMap(Class targetType) { + return contract.parseAndValidatateMetadata(targetType) + .stream().collect(Collectors.toMap(MethodMetadata::configKey, this::requestMetadata)); + } + + private RequestMetadata requestMetadata(MethodMetadata methodMetadata) { + return new RequestMetadata(methodMetadata.template()); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboRegistration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboRegistration.java new file mode 100644 index 00000000..9a435ff2 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboRegistration.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.registry; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; + +import java.net.URI; +import java.util.Map; + +/** + * The {@link Registration} of Dubbo uses an external of {@link ServiceInstance} instance as the delegate. + * + * @author Mercy + */ +class DubboRegistration implements Registration { + + private final ServiceInstance delegate; + + public DubboRegistration(ServiceInstance delegate) { + this.delegate = delegate; + } + + @Override + public String getServiceId() { + return delegate.getServiceId(); + } + + @Override + public String getHost() { + return delegate.getHost(); + } + + @Override + public int getPort() { + return delegate.getPort(); + } + + @Override + public boolean isSecure() { + return delegate.isSecure(); + } + + @Override + public URI getUri() { + return delegate.getUri(); + } + + @Override + public Map getMetadata() { + return delegate.getMetadata(); + } + + @Override + public String getScheme() { + return delegate.getScheme(); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java new file mode 100644 index 00000000..1904cbd5 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java @@ -0,0 +1,443 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.registry; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubbo.common.utils.UrlUtils; +import com.alibaba.dubbo.registry.NotifyListener; +import com.alibaba.dubbo.registry.RegistryFactory; +import com.alibaba.dubbo.registry.support.FailbackRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY; +import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY; +import static com.alibaba.dubbo.common.Constants.PROTOCOL_KEY; +import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY; +import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY; + +/** + * Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud" + * + * @author Mercy + */ +public class SpringCloudRegistry extends FailbackRegistry { + + /** + * All supported categories + */ + private static final String[] ALL_SUPPORTED_CATEGORIES = of( + PROVIDERS_CATEGORY, + CONSUMERS_CATEGORY, + ROUTERS_CATEGORY, + CONFIGURATORS_CATEGORY + ); + + private static final int CATEGORY_INDEX = 0; + + private static final int PROTOCOL_INDEX = CATEGORY_INDEX + 1; + + private static final int SERVICE_INTERFACE_INDEX = PROTOCOL_INDEX + 1; + + private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1; + + private static final int SERVICE_GROUP_INDEX = SERVICE_VERSION_INDEX + 1; + + private static final String WILDCARD = "*"; + + /** + * The separator for service name + */ + private static final String SERVICE_NAME_SEPARATOR = ":"; + + private final ServiceRegistry serviceRegistry; + + private final DiscoveryClient discoveryClient; + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * {@link ScheduledExecutorService} lookup service names(only for Dubbo-OPS) + */ + private volatile ScheduledExecutorService scheduledExecutorService; + + /** + * The interval in second of lookup service names(only for Dubbo-OPS) + */ + private static final long LOOKUP_INTERVAL = Long.getLong("dubbo.service.names.lookup.interval", 30); + + public SpringCloudRegistry(URL url, ServiceRegistry serviceRegistry, + DiscoveryClient discoveryClient) { + super(url); + this.serviceRegistry = serviceRegistry; + this.discoveryClient = discoveryClient; + } + + @Override + protected void doRegister(URL url) { + final String serviceName = getServiceName(url); + final Registration registration = createRegistration(serviceName, url); + serviceRegistry.register(registration); + } + + @Override + protected void doUnregister(URL url) { + final String serviceName = getServiceName(url); + final Registration registration = createRegistration(serviceName, url); + this.serviceRegistry.deregister(registration); + } + + @Override + protected void doSubscribe(URL url, NotifyListener listener) { + List serviceNames = getServiceNames(url, listener); + doSubscribe(url, listener, serviceNames); + } + + @Override + protected void doUnsubscribe(URL url, NotifyListener listener) { + if (isAdminProtocol(url)) { + shutdownServiceNamesLookup(); + } + } + + @Override + public boolean isAvailable() { + return false; + } + + private void shutdownServiceNamesLookup() { + if (scheduledExecutorService != null) { + scheduledExecutorService.shutdown(); + } + } + + private Registration createRegistration(String serviceName, URL url) { + return new DubboRegistration(createServiceInstance(serviceName, url)); + } + + private ServiceInstance createServiceInstance(String serviceName, URL url) { + // Append default category if absent + String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); + URL newURL = url.addParameter(Constants.CATEGORY_KEY, category); + newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol()); + String ip = NetUtils.getLocalHost(); + int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort()); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(serviceName, ip, port, false); + serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters())); + return serviceInstance; + } + + public static String getServiceName(URL url) { + String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY); + return getServiceName(url, category); + } + + private static String getServiceName(URL url, String category) { + StringBuilder serviceNameBuilder = new StringBuilder(category); + appendIfPresent(serviceNameBuilder, url.getParameter(PROTOCOL_KEY, url.getProtocol())); + appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY); + appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY); + appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY); + return serviceNameBuilder.toString(); + } + + private static void appendIfPresent(StringBuilder target, URL url, String parameterName) { + String parameterValue = url.getParameter(parameterName); + appendIfPresent(target, parameterValue); + } + + private static void appendIfPresent(StringBuilder target, String parameterValue) { + if (StringUtils.hasText(parameterValue)) { + target.append(SERVICE_NAME_SEPARATOR).append(parameterValue); + } + } + + private void filterServiceNames(List serviceNames, URL url) { + + final String[] categories = getCategories(url); + + final String targetServiceInterface = url.getServiceInterface(); + + final String targetVersion = url.getParameter(Constants.VERSION_KEY); + + final String targetGroup = url.getParameter(Constants.GROUP_KEY); + + filter(serviceNames, new Filter() { + @Override + public boolean accept(String serviceName) { + // split service name to segments + // (required) segments[0] = category + // (required) segments[1] = serviceInterface + // (required) segments[2] = protocol + // (required) segments[3] = version + // (optional) segments[4] = group + String[] segments = getServiceSegments(serviceName); + int length = segments.length; + if (length < 4) { // must present 4 segments or more + return false; + } + + String category = getCategory(segments); + if (Arrays.binarySearch(categories, category) > -1) { // no match category + return false; + } + + String protocol = getProtocol(segments); + if (StringUtils.hasText(protocol)) { + return false; + } + + String serviceInterface = getServiceInterface(segments); + if (!WILDCARD.equals(targetServiceInterface) && + !Objects.equals(targetServiceInterface, serviceInterface)) { // no match service interface + return false; + } + + String version = getServiceVersion(segments); + if (!WILDCARD.equals(targetVersion) && + !Objects.equals(targetVersion, version)) { // no match service version + return false; + } + + String group = getServiceGroup(segments); + if (group != null && !WILDCARD.equals(targetGroup) + && !Objects.equals(targetGroup, group)) { // no match service group + return false; + } + + return true; + } + }); + } + + public static String[] getServiceSegments(String serviceName) { + return StringUtils.delimitedListToStringArray(serviceName, SERVICE_NAME_SEPARATOR); + } + + public static String getCategory(String[] segments) { + return segments[CATEGORY_INDEX]; + } + + public static String getProtocol(String[] segments) { + return segments[PROTOCOL_INDEX]; + } + + public static String getServiceInterface(String[] segments) { + return segments[SERVICE_INTERFACE_INDEX]; + } + + public static String getServiceVersion(String[] segments) { + return segments[SERVICE_VERSION_INDEX]; + } + + public static String getServiceGroup(String[] segments) { + return segments.length > 4 ? segments[SERVICE_GROUP_INDEX] : null; + } + + /** + * Get the categories from {@link URL} + * + * @param url {@link URL} + * @return non-null array + */ + private String[] getCategories(URL url) { + return Constants.ANY_VALUE.equals(url.getServiceInterface()) ? + ALL_SUPPORTED_CATEGORIES : of(Constants.DEFAULT_CATEGORY); + } + + private List getAllServiceNames() { + return discoveryClient.getServices(); + } + + /** + * Get the service names from the specified {@link URL url} + * + * @param url {@link URL} + * @param listener {@link NotifyListener} + * @return non-null + */ + private List getServiceNames(URL url, NotifyListener listener) { + if (isAdminProtocol(url)) { + scheduleServiceNamesLookup(url, listener); + return getServiceNamesForOps(url); + } else { + return doGetServiceNames(url); + } + } + + + private boolean isAdminProtocol(URL url) { + return Constants.ADMIN_PROTOCOL.equals(url.getProtocol()); + } + + private void scheduleServiceNamesLookup(final URL url, final NotifyListener listener) { + if (scheduledExecutorService == null) { + scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + scheduledExecutorService.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + List serviceNames = getAllServiceNames(); + filter(serviceNames, new Filter() { + @Override + public boolean accept(String serviceName) { + boolean accepted = false; + for (String category : ALL_SUPPORTED_CATEGORIES) { + String prefix = category + SERVICE_NAME_SEPARATOR; + if (StringUtils.startsWithIgnoreCase(serviceName, prefix)) { + accepted = true; + break; + } + } + return accepted; + } + }); + doSubscribe(url, listener, serviceNames); + } + }, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS); + } + } + + private void doSubscribe(final URL url, final NotifyListener listener, final List serviceNames) { + for (String serviceName : serviceNames) { + List serviceInstances = discoveryClient.getInstances(serviceName); + notifySubscriber(url, listener, serviceInstances); + // TODO Support Update notification event + } + } + + private List doGetServiceNames(URL url) { + String[] categories = getCategories(url); + List serviceNames = new ArrayList(categories.length); + for (String category : categories) { + final String serviceName = getServiceName(url, category); + serviceNames.add(serviceName); + } + return serviceNames; + } + + /** + * Notify the Healthy {@link ServiceInstance service instance} to subscriber. + * + * @param url {@link URL} + * @param listener {@link NotifyListener} + * @param serviceInstances all {@link ServiceInstance instances} + */ + private void notifySubscriber(URL url, NotifyListener listener, List serviceInstances) { + List healthyInstances = new LinkedList(serviceInstances); + // Healthy Instances + filterHealthyInstances(healthyInstances); + List urls = buildURLs(url, healthyInstances); + this.notify(url, listener, urls); + } + + private void filterHealthyInstances(Collection instances) { + filter(instances, new Filter() { + @Override + public boolean accept(ServiceInstance data) { + // TODO check the details of status +// return serviceRegistry.getStatus(new DubboRegistration(data)) != null; + return true; + } + }); + } + + private List buildURLs(URL consumerURL, Collection serviceInstances) { + if (serviceInstances.isEmpty()) { + return Collections.emptyList(); + } + List urls = new LinkedList(); + for (ServiceInstance serviceInstance : serviceInstances) { + URL url = buildURL(serviceInstance); + if (UrlUtils.isMatch(consumerURL, url)) { + urls.add(url); + } + } + return urls; + } + + private URL buildURL(ServiceInstance serviceInstance) { + URL url = new URL(serviceInstance.getMetadata().get(Constants.PROTOCOL_KEY), + serviceInstance.getHost(), + serviceInstance.getPort(), + serviceInstance.getMetadata()); + return url; + } + + /** + * Get the service names for Dubbo OPS + * + * @param url {@link URL} + * @return non-null + */ + private List getServiceNamesForOps(URL url) { + List serviceNames = getAllServiceNames(); + filterServiceNames(serviceNames, url); + return serviceNames; + } + + private void filter(Collection collection, Filter filter) { + Iterator iterator = collection.iterator(); + while (iterator.hasNext()) { + T data = iterator.next(); + if (!filter.accept(data)) { // remove if not accept + iterator.remove(); + } + } + } + + private static T[] of(T... values) { + return values; + } + + /** + * A filter + */ + private interface Filter { + + /** + * Tests whether or not the specified data should be accepted. + * + * @param data The data to be tested + * @return true if and only if data + * should be accepted + */ + boolean accept(T data); + + } + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java new file mode 100644 index 00000000..7402ff97 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.registry; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.registry.Registry; +import com.alibaba.dubbo.registry.RegistryFactory; + +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.context.ApplicationContext; + +/** + * Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud" + * + * @author Mercy + * @see RegistryFactory + * @see SpringCloudRegistry + */ +public class SpringCloudRegistryFactory implements RegistryFactory { + + private static ApplicationContext applicationContext; + + @Override + public Registry getRegistry(URL url) { + ServiceRegistry serviceRegistry = applicationContext.getBean(ServiceRegistry.class); + DiscoveryClient discoveryClient = applicationContext.getBean(DiscoveryClient.class); + return new SpringCloudRegistry(url, serviceRegistry, discoveryClient); + } + + public static void setApplicationContext(ApplicationContext applicationContext) { + SpringCloudRegistryFactory.applicationContext = applicationContext; + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory new file mode 100644 index 00000000..77ac945a --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory @@ -0,0 +1 @@ +spring-cloud=org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistryFactory \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..c2627f86 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\ + org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestMetadataRegistrationAutoConfiguration + +org.springframework.context.ApplicationContextInitializer=\ + org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfigurationTest.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfigurationTest.java new file mode 100644 index 00000000..ce32e641 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfigurationTest.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.autoconfigure; + +import org.springframework.boot.test.context.SpringBootTest; + +/** + * {@link DubboServiceRegistrationAutoConfiguration} Test + * + * @author Mercy + */ +@SpringBootTest +public class DubboServiceRegistrationAutoConfigurationTest { +} diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java new file mode 100644 index 00000000..d7b3d13d --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.bootstrap; + +import com.alibaba.dubbo.config.annotation.Reference; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.alibaba.dubbo.service.EchoService; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * Dubbo Spring Cloud Bootstrap + */ +@EnableDiscoveryClient +@EnableAutoConfiguration +@EnableFeignClients +@RestController +public class DubboSpringCloudBootstrap { + + @Reference(version = "1.0.0") + private EchoService echoService; + + @Autowired + @Lazy + private FeignEchoService feignEchoService; + + @GetMapping(value = "/call/echo") + public String echo(@RequestParam("message") String message) { + return feignEchoService.echo(message); + } + + @FeignClient("spring-cloud-alibaba-dubbo") + public interface FeignEchoService { + + @GetMapping(value = "/echo") + String echo(@RequestParam("message") String message); + } + + @Bean + public ApplicationRunner applicationRunner() { + return arguments -> { + // Dubbo Service call + System.out.println(echoService.echo("mercyblitz")); + // Spring Cloud Open Feign REST Call + System.out.println(feignEchoService.echo("mercyblitz")); + }; + } + + public static void main(String[] args) { + new SpringApplicationBuilder(DubboSpringCloudBootstrap.class) + .run(args); + } +} + + + diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java new file mode 100644 index 00000000..e1ad9a9d --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/DefaultEchoService.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.service; + +import com.alibaba.dubbo.config.annotation.Service; +import com.alibaba.dubbo.rpc.RpcContext; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; + +/** + * Default {@link EchoService} + * + * @author Mercy + */ +@Service(version = "1.0.0", protocol = {"dubbo", "rest"}) +@RestController +@Path("/") +public class DefaultEchoService implements EchoService { + + @Override + @GetMapping(value = "/echo" +// consumes = MediaType.APPLICATION_JSON_VALUE, +// produces = MediaType.APPLICATION_JSON_UTF8_VALUE + ) + @Path("/echo") + @GET +// @Consumes("application/json") +// @Produces("application/json;charset=UTF-8") + public String echo(@RequestParam @QueryParam("message") String message) { + return RpcContext.getContext().getUrl() + " [echo] : " + message; + } + + @Override + @PostMapping("/plus") + @Path("/plus") + @POST + public String plus(@RequestParam @QueryParam("a") int a, @RequestParam @QueryParam("b") int b) { + return null; + } +} diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/EchoService.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/EchoService.java new file mode 100644 index 00000000..10ace8ec --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/EchoService.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.springframework.cloud.alibaba.dubbo.service; + +/** + * Echo Service + * + * @author Mercy + */ +public interface EchoService { + + String echo(String message); + + String plus(int a, int b); + +} diff --git a/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml b/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml new file mode 100644 index 00000000..afdfbfa7 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/resources/application.yaml @@ -0,0 +1,16 @@ +dubbo: + scan: + base-packages: org.springframework.cloud.alibaba.dubbo.service + protocols: + dubbo: + name: dubbo + port: 12345 + rest: + name: rest + port: 9090 + server: netty + registry: + address: spring-cloud://nacos + +server: + port: 8080 \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml new file mode 100644 index 00000000..c3799608 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml @@ -0,0 +1,28 @@ +spring: + application: + name: spring-cloud-alibaba-dubbo + cloud: + nacos: + discovery: + server-addr: 127.0.0.1:8848 + config: + server-addr: 127.0.0.1:8848 + +eureka: + client: + enabled: false + +--- +spring: + profiles: eureka + cloud: + nacos: + discovery: + enabled: false + register-enabled: false + +eureka: + client: + enabled: true + service-url: + defaultZone: http://127.0.0.1:8761/eureka/ \ No newline at end of file diff --git a/spring-cloud-alibaba-examples/env-extension/src/main/java/org/springframework/alicloud/env/extension/ImportExtraConfig.java b/spring-cloud-alibaba-examples/env-extension/src/main/java/org/springframework/alicloud/env/extension/ImportExtraConfig.java index cfea09fa..1585c4a9 100644 --- a/spring-cloud-alibaba-examples/env-extension/src/main/java/org/springframework/alicloud/env/extension/ImportExtraConfig.java +++ b/spring-cloud-alibaba-examples/env-extension/src/main/java/org/springframework/alicloud/env/extension/ImportExtraConfig.java @@ -1,7 +1,11 @@ package org.springframework.alicloud.env.extension; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/pom.xml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/pom.xml index 868bc10c..f3bd3370 100644 --- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/pom.xml +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/pom.xml @@ -30,7 +30,11 @@ com.alibaba.boot dubbo-spring-boot-starter - 0.2.0 + + + + com.alibaba + dubbo diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/pom.xml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/pom.xml index 684a589b..6aff02b3 100644 --- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/pom.xml +++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/pom.xml @@ -29,8 +29,13 @@ com.alibaba.boot dubbo-spring-boot-starter - 0.2.0 + + + com.alibaba + dubbo + + diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/NacosConfigProperties.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/NacosConfigProperties.java index 8a7be505..4fefa863 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/NacosConfigProperties.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/NacosConfigProperties.java @@ -30,7 +30,14 @@ import java.util.List; import java.util.Objects; import java.util.Properties; -import static com.alibaba.nacos.api.PropertyKeyConst.*; +import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY; +import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME; +import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH; +import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE; +import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT; +import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE; +import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY; +import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR; /** * nacos properties diff --git a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/client/NacosPropertySourceBuilder.java b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/client/NacosPropertySourceBuilder.java index 1b853704..c820d8b0 100644 --- a/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/client/NacosPropertySourceBuilder.java +++ b/spring-cloud-alibaba-nacos-config/src/main/java/org/springframework/cloud/alibaba/nacos/client/NacosPropertySourceBuilder.java @@ -26,7 +26,11 @@ import org.springframework.core.io.ByteArrayResource; import org.springframework.util.StringUtils; import java.io.StringReader; -import java.util.*; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; /** * @author xiaojing diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java index 38396bb9..ffd67df5 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java @@ -16,10 +16,11 @@ package org.springframework.cloud.alibaba.nacos; +import org.springframework.boot.ApplicationRunner; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.alibaba.nacos.registry.NacosAutoServiceRegistration; @@ -34,36 +35,54 @@ import org.springframework.context.annotation.Configuration; /** * @author xiaojing + * @author Mercy */ - @Configuration @EnableConfigurationProperties @ConditionalOnNacosDiscoveryEnabled -@ConditionalOnClass(name = "org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent") @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -@AutoConfigureAfter(AutoServiceRegistrationAutoConfiguration.class) +@AutoConfigureBefore({AutoServiceRegistrationAutoConfiguration.class, + NacosDiscoveryClientAutoConfiguration.class}) +@AutoConfigureAfter(AutoServiceRegistrationConfiguration.class) public class NacosDiscoveryAutoConfiguration { - @Bean - public NacosServiceRegistry nacosServiceRegistry() { - return new NacosServiceRegistry(); - } + @Bean + public NacosServiceRegistry nacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) { + return new NacosServiceRegistry(nacosDiscoveryProperties); + } - @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) - public NacosRegistration nacosRegistration( - NacosDiscoveryProperties nacosDiscoveryProperties, - ApplicationContext context) { - return new NacosRegistration(nacosDiscoveryProperties, context); - } + @Bean + @ConditionalOnBean(AutoServiceRegistrationProperties.class) + public NacosRegistration nacosRegistration( + NacosDiscoveryProperties nacosDiscoveryProperties, + ApplicationContext context) { + return new NacosRegistration(nacosDiscoveryProperties, context); + } - @Bean - @ConditionalOnBean(AutoServiceRegistrationProperties.class) - public NacosAutoServiceRegistration nacosAutoServiceRegistration( - NacosServiceRegistry registry, - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - NacosRegistration registration) { - return new NacosAutoServiceRegistration(registry, - autoServiceRegistrationProperties, registration); - } + @Bean + @ConditionalOnBean(AutoServiceRegistrationProperties.class) + public NacosAutoServiceRegistration nacosAutoServiceRegistration( + NacosServiceRegistry registry, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + NacosRegistration registration) { + return new NacosAutoServiceRegistration(registry, + autoServiceRegistrationProperties, registration); + } + + @Bean + @ConditionalOnBean(NacosAutoServiceRegistration.class) // NacosAutoServiceRegistration should be present + @ConditionalOnNotWebApplication // Not Web Application + public ApplicationRunner applicationRunner(NacosAutoServiceRegistration nacosAutoServiceRegistration) { + return args -> { + // WebServerInitializedEvent should not be multicast in Non-Web environment. + // Whatever, NacosAutoServiceRegistration must be checked it's running or not. + if (!nacosAutoServiceRegistration.isRunning()) { // If it's not running, let it start. + // FIXME: Please make sure "spring.cloud.nacos.discovery.port" must be configured on an available port, + // or the startup or Nacos health check will be failed. + nacosAutoServiceRegistration.start(); + // NacosAutoServiceRegistration will be stopped after its destroy() method is invoked. + // @PreDestroy destroy() -> stop() + } + }; + } } \ No newline at end of file diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryClient.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryClient.java index 67e6b441..9333d8ae 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryClient.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryClient.java @@ -23,7 +23,11 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author xiaojing diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryProperties.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryProperties.java index ed568e24..775a502b 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryProperties.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryProperties.java @@ -39,6 +39,7 @@ import static com.alibaba.nacos.api.PropertyKeyConst.*; /** * @author dungu.zpf * @author xiaojing + * @author Mercy */ @ConfigurationProperties("spring.cloud.nacos.discovery") @@ -379,14 +380,13 @@ public class NacosDiscoveryProperties { properties.put(CLUSTER_NAME, clusterName); properties.put(NAMING_LOAD_CACHE_AT_START, namingLoadCacheAtStart); - try { - namingService = NacosFactory.createNamingService(properties); - return namingService; - } - catch (Exception e) { + try { + namingService = NacosFactory.createNamingService(properties); + } catch (Exception e) { LOGGER.error("create naming service error!properties={},e=,", this, e); return null; } + return namingService; } } diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java index 2356ad0a..0bbee4c2 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/endpoint/NacosDiscoveryEndpointAutoConfiguration.java @@ -20,6 +20,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.Conditi import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.alibaba.nacos.ConditionalOnNacosDiscoveryEnabled; import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -29,6 +30,7 @@ import org.springframework.context.annotation.Configuration; */ @Configuration @ConditionalOnClass(Endpoint.class) +@ConditionalOnNacosDiscoveryEnabled public class NacosDiscoveryEndpointAutoConfiguration { @Bean diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosAutoServiceRegistration.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosAutoServiceRegistration.java index ec60041c..24b0a848 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosAutoServiceRegistration.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosAutoServiceRegistration.java @@ -20,83 +20,85 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * @author xiaojing + * @author Mercy */ public class NacosAutoServiceRegistration - extends AbstractAutoServiceRegistration { - private static final Logger LOGGER = LoggerFactory - .getLogger(NacosAutoServiceRegistration.class); + extends AbstractAutoServiceRegistration { + private static final Logger LOGGER = LoggerFactory + .getLogger(NacosAutoServiceRegistration.class); - private NacosRegistration registration; + private NacosRegistration registration; - public NacosAutoServiceRegistration( - ServiceRegistry serviceRegistry, - AutoServiceRegistrationProperties autoServiceRegistrationProperties, - NacosRegistration registration) { - super(serviceRegistry, autoServiceRegistrationProperties); - this.registration = registration; - } + public NacosAutoServiceRegistration( + ServiceRegistry serviceRegistry, + AutoServiceRegistrationProperties autoServiceRegistrationProperties, + NacosRegistration registration) { + super(serviceRegistry, autoServiceRegistrationProperties); + this.registration = registration; + } - @Deprecated - public void setPort(int port) { - getPort().set(port); - } + @Deprecated + public void setPort(int port) { + getPort().set(port); + } - @Override - protected NacosRegistration getRegistration() { - if (this.registration.getPort() < 0 && this.getPort().get() > 0) { - this.registration.setPort(this.getPort().get()); - } - Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set"); - return this.registration; - } + @Override + protected NacosRegistration getRegistration() { + if (this.registration.getPort() < 0 && this.getPort().get() > 0) { + this.registration.setPort(this.getPort().get()); + } + Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set"); + return this.registration; + } - @Override - protected NacosRegistration getManagementRegistration() { - return null; - } + @Override + protected NacosRegistration getManagementRegistration() { + return null; + } - @Override - protected void register() { - if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { - LOGGER.debug("Registration disabled."); - return; - } - if (this.registration.getPort() < 0) { - this.registration.setPort(getPort().get()); - } - super.register(); - } + @Override + protected void register() { + if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { + LOGGER.debug("Registration disabled."); + return; + } + if (this.registration.getPort() < 0) { + this.registration.setPort(getPort().get()); + } + super.register(); + } - @Override - protected void registerManagement() { - if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { - return; - } - super.registerManagement(); + @Override + protected void registerManagement() { + if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) { + return; + } + super.registerManagement(); - } + } - @Override - protected Object getConfiguration() { - return this.registration.getNacosDiscoveryProperties(); - } + @Override + protected Object getConfiguration() { + return this.registration.getNacosDiscoveryProperties(); + } - @Override - protected boolean isEnabled() { - return this.registration.getNacosDiscoveryProperties().isRegisterEnabled(); - } + @Override + protected boolean isEnabled() { + return this.registration.getNacosDiscoveryProperties().isRegisterEnabled(); + } - @Override - @SuppressWarnings("deprecation") - protected String getAppName() { - String appName = registration.getNacosDiscoveryProperties().getService(); - return StringUtils.isEmpty(appName) ? super.getAppName() : appName; - } + @Override + @SuppressWarnings("deprecation") + protected String getAppName() { + String appName = registration.getNacosDiscoveryProperties().getService(); + return StringUtils.isEmpty(appName) ? super.getAppName() : appName; + } } diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosServiceRegistry.java index f3850a18..121d9f9e 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosServiceRegistry.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/registry/NacosServiceRegistry.java @@ -18,90 +18,97 @@ package org.springframework.cloud.alibaba.nacos.registry; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.util.StringUtils; /** * @author xiaojing + * @author Mercy */ -public class NacosServiceRegistry implements ServiceRegistry { +public class NacosServiceRegistry implements ServiceRegistry { - private static Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class); + private static Logger logger = LoggerFactory.getLogger(NacosServiceRegistry.class); - @Override - public void register(NacosRegistration registration) { + private final NacosDiscoveryProperties nacosDiscoveryProperties; - if (!registration.isRegisterEnabled()) { - logger.info("Nacos Registration is disabled..."); - return; - } - if (StringUtils.isEmpty(registration.getServiceId())) { - logger.info("No service to register for nacos client..."); - return; - } + private final NamingService namingService; - NamingService namingService = registration.getNacosNamingService(); - String serviceId = registration.getServiceId(); + public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) { + this.nacosDiscoveryProperties = nacosDiscoveryProperties; + this.namingService = nacosDiscoveryProperties.namingServiceInstance(); + } - Instance instance = new Instance(); - instance.setIp(registration.getHost()); - instance.setPort(registration.getPort()); - instance.setWeight(registration.getRegisterWeight()); - instance.setClusterName(registration.getCluster()); - instance.setMetadata(registration.getMetadata()); - try { - namingService.registerInstance(serviceId, instance); - logger.info("nacos registry, {} {}:{} register finished", serviceId, - instance.getIp(), instance.getPort()); - } - catch (Exception e) { - logger.error("nacos registry, {} register failed...{},", serviceId, - registration.toString(), e); - } - } + @Override + public void register(Registration registration) { - @Override - public void deregister(NacosRegistration registration) { + if (StringUtils.isEmpty(registration.getServiceId())) { + logger.info("No service to register for nacos client..."); + return; + } - logger.info("De-registering from Nacos Server now..."); + String serviceId = registration.getServiceId(); - if (StringUtils.isEmpty(registration.getServiceId())) { - logger.info("No dom to de-register for nacos client..."); - return; - } + Instance instance = new Instance(); + instance.setIp(registration.getHost()); + instance.setPort(registration.getPort()); + instance.setWeight(nacosDiscoveryProperties.getWeight()); + instance.setClusterName(nacosDiscoveryProperties.getClusterName()); + instance.setMetadata(registration.getMetadata()); - NamingService namingService = registration.getNacosNamingService(); - String serviceId = registration.getServiceId(); + try { + namingService.registerInstance(serviceId, instance); + logger.info("nacos registry, {} {}:{} register finished", serviceId, + instance.getIp(), instance.getPort()); + } catch (Exception e) { + logger.error("nacos registry, {} register failed...{},", serviceId, + registration.toString(), e); + } + } - try { - namingService.deregisterInstance(serviceId, registration.getHost(), - registration.getPort(), registration.getCluster()); - } - catch (Exception e) { - logger.error("ERR_NACOS_DEREGISTER, de-register failed...{},", - registration.toString(), e); - } + @Override + public void deregister(Registration registration) { - logger.info("De-registration finished."); - } + logger.info("De-registering from Nacos Server now..."); - @Override - public void close() { + if (StringUtils.isEmpty(registration.getServiceId())) { + logger.info("No dom to de-register for nacos client..."); + return; + } - } + NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); + String serviceId = registration.getServiceId(); - @Override - public void setStatus(NacosRegistration registration, String status) { - // nacos doesn't support set status of a particular registration. - } + try { + namingService.deregisterInstance(serviceId, registration.getHost(), + registration.getPort(), nacosDiscoveryProperties.getClusterName()); + } catch (Exception e) { + logger.error("ERR_NACOS_DEREGISTER, de-register failed...{},", + registration.toString(), e); + } - @Override - public T getStatus(NacosRegistration registration) { - // nacos doesn't support query status of a particular registration. - return null; - } + logger.info("De-registration finished."); + } + + @Override + public void close() { + + } + + @Override + public void setStatus(Registration registration, String status) { + // nacos doesn't support set status of a particular registration. + } + + @Override + public T getStatus(Registration registration) { + // nacos doesn't support query status of a particular registration. + return null; + } } diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosServerList.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosServerList.java index 6b83e83c..02195546 100644 --- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosServerList.java +++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/ribbon/NacosServerList.java @@ -16,6 +16,7 @@ package org.springframework.cloud.alibaba.nacos.ribbon; +import com.alibaba.nacos.api.naming.pojo.Instance; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AbstractServerList; import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; @@ -23,8 +24,6 @@ import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties; import java.util.ArrayList; import java.util.List; -import com.alibaba.nacos.api.naming.pojo.Instance; - /** * @author xiaojing * @author renhaojun diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java index f8bf8528..9df4d473 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/config/NacosDataSourceProperties.java @@ -2,6 +2,8 @@ package org.springframework.cloud.alibaba.sentinel.datasource.config; import javax.validation.constraints.NotEmpty; +import org.springframework.cloud.alibaba.sentinel.datasource.RuleType; +import org.springframework.cloud.alibaba.sentinel.datasource.SentinelDataSourceConstants; import org.springframework.cloud.alibaba.sentinel.datasource.factorybean.NacosDataSourceFactoryBean; import org.springframework.util.StringUtils; diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java index 7d4e65b4..d7894418 100644 --- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java +++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/factorybean/NacosDataSourceFactoryBean.java @@ -1,13 +1,12 @@ package org.springframework.cloud.alibaba.sentinel.datasource.factorybean; -import java.util.Properties; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.util.StringUtils; - import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource; import com.alibaba.nacos.api.PropertyKeyConst; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.util.StringUtils; + +import java.util.Properties; /** * A {@link FactoryBean} for creating {@link NacosDataSource} instance. diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java index 53aea051..d4621bd7 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java @@ -16,18 +16,17 @@ package org.springframework.cloud.alibaba.sentinel; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - +import com.alibaba.csp.sentinel.config.SentinelConfig; +import com.alibaba.csp.sentinel.log.LogBase; +import com.alibaba.csp.sentinel.transport.config.TransportConfig; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePropertiesConfiguration; import org.springframework.core.Ordered; import org.springframework.validation.annotation.Validated; -import com.alibaba.csp.sentinel.config.SentinelConfig; -import com.alibaba.csp.sentinel.log.LogBase; -import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; /** * {@link ConfigurationProperties} for Sentinel. diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelWebAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelWebAutoConfiguration.java index d70fe785..c9699e66 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelWebAutoConfiguration.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelWebAutoConfiguration.java @@ -16,11 +16,7 @@ package org.springframework.cloud.alibaba.sentinel; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.Filter; - +import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,7 +27,9 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter; +import javax.servlet.Filter; +import java.util.ArrayList; +import java.util.List; /** * @author xiaojing diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java index 27739845..26613a42 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java @@ -16,25 +16,6 @@ package org.springframework.cloud.alibaba.sentinel.custom; -import java.util.Optional; - -import javax.annotation.PostConstruct; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.alibaba.sentinel.SentinelProperties; -import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter; -import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler; import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner; @@ -51,9 +32,25 @@ import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; import com.alibaba.csp.sentinel.slots.system.SystemRule; import com.alibaba.csp.sentinel.transport.config.TransportConfig; import com.alibaba.csp.sentinel.util.AppNameUtil; - import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.alibaba.sentinel.SentinelProperties; +import org.springframework.cloud.alibaba.sentinel.datasource.converter.JsonConverter; +import org.springframework.cloud.alibaba.sentinel.datasource.converter.XmlConverter; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import javax.annotation.PostConstruct; +import java.util.Optional; /** * @author xiaojing diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java index 18580aa5..4b222d01 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java @@ -16,10 +16,7 @@ package org.springframework.cloud.alibaba.sentinel.custom; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.concurrent.ConcurrentHashMap; - +import com.alibaba.csp.sentinel.slots.block.BlockException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -40,7 +37,9 @@ import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; -import com.alibaba.csp.sentinel.slots.block.BlockException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; /** * PostProcessor handle @SentinelRestTemplate Annotation, add interceptor for RestTemplate diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java index 49bd003f..a6dcb3c0 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java @@ -16,11 +16,12 @@ package org.springframework.cloud.alibaba.sentinel.custom; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URI; - +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; +import com.alibaba.csp.sentinel.context.ContextUtil; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate; @@ -30,12 +31,10 @@ import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; -import com.alibaba.csp.sentinel.Entry; -import com.alibaba.csp.sentinel.SphU; -import com.alibaba.csp.sentinel.Tracer; -import com.alibaba.csp.sentinel.context.ContextUtil; -import com.alibaba.csp.sentinel.slots.block.BlockException; -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; /** * Interceptor using by SentinelRestTemplate diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java index df893442..f42898bc 100644 --- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java +++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java @@ -16,22 +16,21 @@ package org.springframework.cloud.alibaba.sentinel.endpoint; -import java.util.HashMap; -import java.util.Map; - -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.cloud.alibaba.sentinel.SentinelProperties; - import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig; import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.log.LogBase; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager; import com.alibaba.csp.sentinel.slots.system.SystemRuleManager; import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.cloud.alibaba.sentinel.SentinelProperties; + +import java.util.HashMap; +import java.util.Map; /** * Endpoint for Sentinel, contains ans properties and rules diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelAutoConfigurationTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelAutoConfigurationTests.java index 2cd3b53a..138c6502 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelAutoConfigurationTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelAutoConfigurationTests.java @@ -16,15 +16,16 @@ package org.springframework.cloud.alibaba.sentinel; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.mock; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -import java.util.Arrays; -import java.util.Map; - +import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig; +import com.alibaba.csp.sentinel.config.SentinelConfig; +import com.alibaba.csp.sentinel.log.LogBase; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import com.alibaba.csp.sentinel.transport.config.TransportConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,16 +51,14 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; -import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig; -import com.alibaba.csp.sentinel.config.SentinelConfig; -import com.alibaba.csp.sentinel.log.LogBase; -import com.alibaba.csp.sentinel.slots.block.BlockException; -import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; -import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; -import com.alibaba.csp.sentinel.transport.config.TransportConfig; +import java.util.Arrays; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; /** * @author Jim diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelBeanAutowiredTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelBeanAutowiredTests.java index b22f17e8..ed24c33f 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelBeanAutowiredTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelBeanAutowiredTests.java @@ -16,14 +16,12 @@ package org.springframework.cloud.alibaba.sentinel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; +import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler; +import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner; +import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager; +import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil; +import com.alibaba.csp.sentinel.slots.block.BlockException; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -35,12 +33,12 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; -import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; -import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler; -import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner; -import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager; -import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil; -import com.alibaba.csp.sentinel.slots.block.BlockException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * @author Jim diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelDataSourceTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelDataSourceTests.java index 13a6e322..1c3be389 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelDataSourceTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelDataSourceTests.java @@ -16,10 +16,6 @@ package org.springframework.cloud.alibaba.sentinel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +27,10 @@ import org.springframework.cloud.alibaba.sentinel.datasource.RuleType; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringRunner; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + /** * @author Jim */ diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java index 3f56f700..b7d03670 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelFeignTests.java @@ -16,14 +16,9 @@ package org.springframework.cloud.alibaba.sentinel; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Arrays; - +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -40,9 +35,13 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import com.alibaba.csp.sentinel.slots.block.RuleConstant; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; -import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; /** * @author Jim diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelRestTemplateTests.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelRestTemplateTests.java index f43af925..f95c4616 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelRestTemplateTests.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/SentinelRestTemplateTests.java @@ -16,8 +16,7 @@ package org.springframework.cloud.alibaba.sentinel; -import static org.junit.Assert.assertEquals; - +import com.alibaba.csp.sentinel.slots.block.BlockException; import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate; @@ -31,7 +30,7 @@ import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.web.client.RestTemplate; -import com.alibaba.csp.sentinel.slots.block.BlockException; +import static org.junit.Assert.assertEquals; /** * @author Jim diff --git a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/TestConverter.java b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/TestConverter.java index e7247a41..43012442 100644 --- a/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/TestConverter.java +++ b/spring-cloud-alibaba-sentinel/src/test/java/org/springframework/cloud/alibaba/sentinel/TestConverter.java @@ -16,15 +16,14 @@ package org.springframework.cloud.alibaba.sentinel; -import java.io.IOException; -import java.util.List; - import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule; - import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; + /** * @author Jim */ diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java index 46e1a1bb..36c28c9f 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/AnsDiscoveryClient.java @@ -21,7 +21,12 @@ import com.alibaba.ans.shaded.com.taobao.vipserver.client.core.Host; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * @author xiaolongzuo diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRefreshEventListener.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRefreshEventListener.java index bb1ac8fa..70d12113 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRefreshEventListener.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRefreshEventListener.java @@ -1,17 +1,15 @@ package org.springframework.cloud.alicloud.ans.migrate; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import javax.annotation.PostConstruct; - +import com.netflix.loadbalancer.ILoadBalancer; import org.springframework.cloud.context.named.NamedContextFactory; import org.springframework.cloud.endpoint.event.RefreshEvent; import org.springframework.context.ApplicationListener; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import com.netflix.loadbalancer.ILoadBalancer; +import javax.annotation.PostConstruct; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * @author pbting diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRibbonBeanPostProcessor.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRibbonBeanPostProcessor.java index c863399b..98fe851e 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRibbonBeanPostProcessor.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/MigrateRibbonBeanPostProcessor.java @@ -1,15 +1,14 @@ package org.springframework.cloud.alicloud.ans.migrate; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.loadbalancer.ServerList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.config.BeanPostProcessor; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.ServerList; - public class MigrateRibbonBeanPostProcessor implements BeanPostProcessor, BeanClassLoaderAware { diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/ServerListInvocationHandler.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/ServerListInvocationHandler.java index 23964363..16a31147 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/ServerListInvocationHandler.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/migrate/ServerListInvocationHandler.java @@ -9,7 +9,12 @@ import org.apache.commons.logging.LogFactory; import org.springframework.cloud.alicloud.ans.ribbon.AnsServer; import org.springframework.cloud.alicloud.ans.ribbon.AnsServerList; -import java.util.*; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListSet; diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/registry/AnsRegistration.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/registry/AnsRegistration.java index 79be8e85..5cbcb732 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/registry/AnsRegistration.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/registry/AnsRegistration.java @@ -16,11 +16,6 @@ package org.springframework.cloud.alicloud.ans.registry; -import java.net.URI; -import java.util.Map; - -import javax.annotation.PostConstruct; - import org.springframework.cloud.alicloud.context.ans.AnsProperties; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; @@ -30,6 +25,10 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; +import javax.annotation.PostConstruct; +import java.net.URI; +import java.util.Map; + /** * @author xiaolongzuo */ diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/AnsRibbonClientConfiguration.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/AnsRibbonClientConfiguration.java index 93393ed9..3f1f1516 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/AnsRibbonClientConfiguration.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/AnsRibbonClientConfiguration.java @@ -16,15 +16,14 @@ package org.springframework.cloud.alicloud.ans.ribbon; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.ServerList; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.alicloud.ans.migrate.MigrateOnConditionMissingClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.ServerList; - /** * @author xiaolongzuo */ diff --git a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/MigrateRibbonCofiguration.java b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/MigrateRibbonCofiguration.java index 5bda207c..9074b786 100644 --- a/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/MigrateRibbonCofiguration.java +++ b/spring-cloud-alicloud-ans/src/main/java/org/springframework/cloud/alicloud/ans/ribbon/MigrateRibbonCofiguration.java @@ -1,13 +1,12 @@ package org.springframework.cloud.alicloud.ans.ribbon; -import org.springframework.cloud.alicloud.ans.migrate.MigrateRibbonBeanPostProcessor; +import com.netflix.client.config.IClientConfig; import org.springframework.cloud.alicloud.ans.migrate.MigrateOnConditionClass; +import org.springframework.cloud.alicloud.ans.migrate.MigrateRibbonBeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import com.netflix.client.config.IClientConfig; - @Configuration @Conditional(MigrateOnConditionClass.class) public class MigrateRibbonCofiguration { diff --git a/spring-cloud-alicloud-context/src/main/java/org/springframework/cloud/alicloud/context/scx/ScxContextAutoConfiguration.java b/spring-cloud-alicloud-context/src/main/java/org/springframework/cloud/alicloud/context/scx/ScxContextAutoConfiguration.java index a2b738fd..ab391d21 100644 --- a/spring-cloud-alicloud-context/src/main/java/org/springframework/cloud/alicloud/context/scx/ScxContextAutoConfiguration.java +++ b/spring-cloud-alicloud-context/src/main/java/org/springframework/cloud/alicloud/context/scx/ScxContextAutoConfiguration.java @@ -16,6 +16,9 @@ package org.springframework.cloud.alicloud.context.scx; +import com.alibaba.cloud.context.edas.AliCloudEdasSdk; +import com.alibaba.cloud.context.scx.AliCloudScxInitializer; +import com.alibaba.edas.schedulerx.SchedulerXClient; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -26,10 +29,6 @@ import org.springframework.cloud.alicloud.context.edas.EdasProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.alibaba.cloud.context.edas.AliCloudEdasSdk; -import com.alibaba.cloud.context.scx.AliCloudScxInitializer; -import com.alibaba.edas.schedulerx.SchedulerXClient; - /** * @author xiaolongzuo */ diff --git a/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java b/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java index 55861e37..dd4c67b1 100644 --- a/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java +++ b/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java @@ -16,14 +16,6 @@ package org.springframework.cloud.stream.binder.rocketmq.integration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - import org.apache.commons.lang3.ClassUtils; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.MessageSelector; @@ -56,6 +48,14 @@ import org.springframework.retry.support.RetryTemplate; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + /** * @author Jim */ diff --git a/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQMessageHandler.java b/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQMessageHandler.java index 6efe7955..f2dd937c 100644 --- a/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQMessageHandler.java +++ b/spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/integration/RocketMQMessageHandler.java @@ -16,10 +16,6 @@ package org.springframework.cloud.stream.binder.rocketmq.integration; -import java.time.Instant; -import java.util.Map; -import java.util.Optional; - import org.apache.rocketmq.client.exception.MQBrokerException; import org.apache.rocketmq.client.exception.MQClientException; import org.apache.rocketmq.client.producer.DefaultMQProducer; @@ -48,6 +44,10 @@ import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.ErrorMessage; import org.springframework.util.Assert; +import java.time.Instant; +import java.util.Map; +import java.util.Optional; + /** * @author Jim */