Skip to content

Commit

Permalink
Merge dev branch
Browse files Browse the repository at this point in the history
  • Loading branch information
mercyblitz committed Jan 19, 2025
1 parent 0988b10 commit 16ec936
Show file tree
Hide file tree
Showing 35 changed files with 480 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ io.microsphere.spring.cloud.client.service.registry.autoconfigure.ServiceRegistr
io.microsphere.spring.cloud.client.service.registry.autoconfigure.WebMvcServiceRegistryAutoConfiguration
io.microsphere.spring.cloud.client.service.registry.autoconfigure.WebFluxServiceRegistryAutoConfiguration
io.microsphere.spring.cloud.client.service.registry.autoconfigure.SimpleAutoServiceRegistrationAutoConfiguration
io.microsphere.spring.cloud.client.service.registry.actuate.autoconfigure.ServiceRegistrationEndpointAutoConfiguration
io.microsphere.spring.cloud.client.service.registry.actuate.autoconfigure.ServiceRegistrationEndpointAutoConfiguration
io.microsphere.spring.cloud.fault.tolerance.tomcat.autoconfigure.TomcatFaultToleranceAutoConfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;

Expand Down Expand Up @@ -41,9 +40,6 @@ public class SimpleAutoServiceRegistrationAutoConfigurationTest {
@Autowired
private SimpleAutoServiceRegistration simpleAutoServiceRegistration;

@LocalServerPort
private Integer port;

@Test
public void test() {
assertEquals("test-service", registration.getServiceId());
Expand All @@ -52,7 +48,6 @@ public void test() {
assertNotNull(registration.getUri());
assertNotNull(registration.getInstanceId());
assertNotNull(registration.getMetadata());
assertNotNull(port);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
Expand All @@ -19,6 +20,7 @@
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Inherited
@Import(EnableFeignAutoRefresh.Marker.class)
public @interface EnableFeignAutoRefresh {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import io.microsphere.spring.cloud.openfeign.autorefresh.FeignComponentRegistry;
import io.microsphere.spring.cloud.openfeign.components.NoOpRequestInterceptor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.openfeign.FeignBuilderCustomizer;
import org.springframework.cloud.openfeign.FeignClientProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;

/**
* The Auto-Configuration class for {@link EnableFeignAutoRefresh}
Expand All @@ -20,7 +21,6 @@
* @since 0.0.1
*/
@ConditionalOnBean(EnableFeignAutoRefresh.Marker.class)
@AutoConfigureAfter(ConfigurationPropertiesRebinderAutoConfiguration.class)
public class FeignClientAutoRefreshAutoConfiguration {

@Bean
Expand All @@ -30,9 +30,12 @@ public FeignBuilderCustomizer addDefaultRequestInterceptorCustomizer() {
};
}

@Bean
public FeignClientConfigurationChangedListener feignClientConfigurationChangedListener(FeignComponentRegistry registry) {
return new FeignClientConfigurationChangedListener(registry);
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReadyEvent(ApplicationReadyEvent event) {
/**
* Make sure the FeignClientConfigurationChangedListener is registered after the ConfigurationPropertiesRebinder
*/
registerFeignClientConfigurationChangedListener(event);
}

@Bean
Expand All @@ -45,4 +48,10 @@ public FeignClientSpecificationPostProcessor feignClientSpecificationPostProcess
return new FeignClientSpecificationPostProcessor();
}

private void registerFeignClientConfigurationChangedListener(ApplicationReadyEvent event) {
ConfigurableApplicationContext context = event.getApplicationContext();
FeignComponentRegistry feignComponentRegistry = context.getBean(FeignComponentRegistry.class);
context.addApplicationListener(new FeignClientConfigurationChangedListener(feignComponentRegistry));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
public class AutoRefreshCapability implements Capability, ApplicationContextAware {

private final FeignComponentRegistry componentRegistry;

private final FeignContext feignContext;

private final FeignClientProperties clientProperties;

private String contextId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ public FeignClientConfigurationChangedListener(FeignComponentRegistry registry)
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
Map<String, Set<String>> effectiveClients = resolveChangedClient(event);
effectiveClients.forEach(registry::refresh);

if (!effectiveClients.isEmpty()) {
effectiveClients.forEach(registry::refresh);
}
}

protected Map<String, Set<String>> resolveChangedClient(EnvironmentChangeEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand All @@ -29,6 +30,10 @@ public CompositedRequestInterceptor(String contextId, BeanFactory beanFactory) {
this.contextId = contextId;
}

public Set<RequestInterceptor> getRequestInterceptors() {
return Collections.unmodifiableSet(set);
}


@Override
public void apply(RequestTemplate template) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
@FeignClient(contextId = "my-client", name = "my-client")
@FeignClient(contextId = "my-client", name = "my-client", configuration = {MockCapability.class})
public interface BaseClient {

@GetMapping("echo")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.endpoint.event.RefreshEvent;
import org.springframework.cloud.openfeign.EnableFeignClients;
Expand All @@ -31,14 +28,17 @@
@TestPropertySource(properties = {
"spring.main.allow-bean-definition-overriding=true",
"feign.client.config.default.encoder=io.microsphere.spring.cloud.openfeign.encoder.AEncoder",
"feign.client.config.default.error-decoder=io.microsphere.spring.cloud.openfeign.errordecoder.AErrorDecoder",
"feign.client.config.default.query-map-encoder=io.microsphere.spring.cloud.openfeign.querymapencoder.AQueryMapEncoder",
"feign.client.config.default.retryer=io.microsphere.spring.cloud.openfeign.retryer.ARetry",
"feign.client.config.default.decoder=io.microsphere.spring.cloud.openfeign.decoder.ADecoder",
"feign.client.config.default.request-interceptors[0]=io.microsphere.spring.cloud.openfeign.requestInterceptor.ARequestInterceptor",
"feign.client.config.default.default-request-headers.app=my-app",
"feign.client.config.default.default-query-parameters.sign=my-sign",
})
@ComponentScan(basePackages = "io.microsphere.spring.cloud.openfeign")
@EnableFeignClients(clients = BaseClient.class)
@EnableFeignAutoRefresh
@AutoConfigureAfter(ConfigurationPropertiesRebinderAutoConfiguration.class)
public abstract class BaseTest<T> {

private static final Logger log = LoggerFactory.getLogger(BaseTest.class);
Expand All @@ -50,7 +50,9 @@ public abstract class BaseTest<T> {
private BaseClient client;

protected abstract String afterTestComponentConfigKey();
protected abstract Class<? extends T> beforeTestComponentClass();
protected abstract Class<? extends T> afterTestComponent();
protected abstract FeignComponentAssert<T> loadFeignComponentAssert();

public void replaceConfig() {
final String key = afterTestComponentConfigKey();
Expand All @@ -71,20 +73,21 @@ public void replaceConfig() {

@Test
public void testInternal() {
ObservableFeignInvocationHandler.componentAssert = loadFeignComponentAssert();

ObservableFeignInvocationHandler.expectComponentClass = beforeTestComponentClass();
try {
this.client.echo("hello", "1.0");

} catch (Exception ignored) {

}
replaceConfig();

ObservableFeignInvocationHandler.expectComponentClass = afterTestComponent();
try {
this.client.echo("world", "1.0");
} catch (Exception ignored) {

}


}

protected void triggerRefreshEvent() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.microsphere.spring.cloud.openfeign;

import feign.InvocationHandlerFactory;

/**
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
public abstract class FeignComponentAssert<T> {


protected abstract T loadCurrentComponent(InvocationHandlerFactory.MethodHandler methodHandler) throws Exception;

public boolean expect(InvocationHandlerFactory.MethodHandler methodHandler, Class<T> expectedClass) throws Exception {
T component = loadCurrentComponent(methodHandler);
return expectedClass.equals(component.getClass());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.microsphere.spring.cloud.openfeign;

import feign.Capability;
import feign.InvocationHandlerFactory;

/**
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
public class MockCapability implements Capability {

@Override
public InvocationHandlerFactory enrich(InvocationHandlerFactory invocationHandlerFactory) {
return ObservableFeignInvocationHandler::new;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.microsphere.spring.cloud.openfeign;

import feign.InvocationHandlerFactory;
import feign.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

import static feign.Util.checkNotNull;

/**
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
public class ObservableFeignInvocationHandler implements InvocationHandler {


private static final Logger log = LoggerFactory.getLogger(ObservableFeignInvocationHandler.class);
public static FeignComponentAssert<?> componentAssert;
public static Class expectComponentClass;

private final Target target;
private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;

ObservableFeignInvocationHandler(Target target, Map<Method, InvocationHandlerFactory.MethodHandler> dispatch) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("equals".equals(method.getName())) {
try {
Object otherHandler =
args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return equals(otherHandler);
} catch (IllegalArgumentException e) {
return false;
}
} else if ("hashCode".equals(method.getName())) {
return hashCode();
} else if ("toString".equals(method.getName())) {
return toString();
} else if (!dispatch.containsKey(method)) {
throw new UnsupportedOperationException(
String.format("Method \"%s\" should not be called", method.getName()));
}

InvocationHandlerFactory.MethodHandler methodHandler = dispatch.get(method);
Assert.isTrue(componentAssert.expect(methodHandler, expectComponentClass), "unexpected component");
log.info("component validation is True");
return dispatch.get(method).invoke(args);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof ObservableFeignInvocationHandler) {
ObservableFeignInvocationHandler other = (ObservableFeignInvocationHandler) obj;
return target.equals(other.target);
}
return false;
}

@Override
public int hashCode() {
return target.hashCode();
}

@Override
public String toString() {
return target.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.microsphere.spring.cloud.openfeign.decoder;

import feign.FeignException;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;

import java.io.IOException;
import java.lang.reflect.Type;

/**
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
public class ADecoder implements Decoder {

@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.microsphere.spring.cloud.openfeign.decoder;

import feign.FeignException;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;

import java.io.IOException;
import java.lang.reflect.Type;

/**
* @author <a href="mailto:[email protected]">韩超</a>
* @since 0.0.1
*/
public class BDecoder implements Decoder {

@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
return null;
}
}
Loading

0 comments on commit 16ec936

Please sign in to comment.