();
+ service.setInterface(markClass);
+ service.setGroup(appId + "-" + markClass.getSimpleName());
+ service.setVersion("1.0.0");
+ service.setRef(genericService);
+ service.setCluster("failfast");
+
+ if(applicationConfig != null) {
+ service.setApplication(applicationConfig);
+ }
+
+ if(registryConfig != null) {
+ service.setRegistry(registryConfig);
+ }
+
+ if(protocolConfig != null) {
+ service.setProtocol(protocolConfig);
+ }
+
+ if(monitorConfig != null) {
+ service.setMonitor(monitorConfig);
+ }
+
+ if(moduleConfig != null) {
+ service.setModule(moduleConfig);
+ }
+
+ if(providerConfig != null) {
+ service.setProvider(providerConfig);
+ }
+
+ if(customizationer != null) {
+ customizationer.customDubboService(null,service);
+ }
+
+ service.export();
+ }
+
+ }
+}
diff --git a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConfiguration.java b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConfiguration.java
index f453b68..c5a9149 100644
--- a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConfiguration.java
+++ b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConfiguration.java
@@ -11,6 +11,7 @@
import org.springframework.context.annotation.Configuration;
import com.yiqiniu.easytrans.filter.EasyTransFilterChainFactory;
+import com.yiqiniu.easytrans.monitor.MonitorConsumerFactory;
import com.yiqiniu.easytrans.rpc.EasyTransRpcConsumer;
import com.yiqiniu.easytrans.rpc.EasyTransRpcProvider;
import com.yiqiniu.easytrans.serialization.ObjectSerializer;
@@ -35,4 +36,16 @@ public RestRibbonEasyTransRpcProviderImpl restRibbonEasyTransRpcProviderImpl(Eas
return new RestRibbonEasyTransRpcProviderImpl(filterChainFactory, serializer);
}
+ @Bean
+ @ConditionalOnProperty(name="easytrans.rpc.rest-ribbon.monitor.enabled",havingValue="true",matchIfMissing=true)
+ public RestRibbonMonitorProvider restRibbonMonitorProvider() {
+ return new RestRibbonMonitorProvider();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(MonitorConsumerFactory.class)
+ public MonitorConsumerFactory monitorConsumerFactory(RestRibbonEasyTransRpcConsumerImpl consumer) {
+ return new RestRibbonMonitorConsumerFactory(consumer);
+ }
+
}
diff --git a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConsumerImpl.java b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConsumerImpl.java
index da3d7ed..15de045 100644
--- a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConsumerImpl.java
+++ b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcConsumerImpl.java
@@ -1,6 +1,8 @@
package com.yiqiniu.easytrans.rpc.impl.rest;
import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
@@ -28,6 +30,7 @@
import com.netflix.loadbalancer.BestAvailableRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
+import com.yiqiniu.easytrans.monitor.EtMonitor;
import com.yiqiniu.easytrans.protocol.EasyTransRequest;
import com.yiqiniu.easytrans.rpc.EasyTransRpcConsumer;
import com.yiqiniu.easytrans.rpc.impl.rest.RestRibbonEasyTransRpcProperties.RestConsumerProperties;
@@ -112,11 +115,7 @@ public RestTemplate getLoadBalancedRestTemplate() {
@Override
public , R extends Serializable> R call(String appId, String busCode, String innerMethod, Map header, P params) {
- RestConsumerProperties restConsumerProperties = properties.getConsumer().get(appId);
- String context = RestRibbonEasyTransConstants.DEFAULT_URL_CONTEXT;
- if(restConsumerProperties!= null && restConsumerProperties.getContext() != null){
- context = restConsumerProperties.getContext();
- }
+ String context = getHttpContext(appId);
Class extends EasyTransRequest> paramsClass = params.getClass();
Class> resultClass = ReflectUtil.getResultClass(paramsClass);
@@ -134,6 +133,41 @@ public RestTemplate getLoadBalancedRestTemplate() {
return (R) exchangeResult.getBody();
}
+ private String getHttpContext(String appId) {
+ RestConsumerProperties restConsumerProperties = properties.getConsumer().get(appId);
+ String context = RestRibbonEasyTransConstants.DEFAULT_URL_CONTEXT;
+ if(restConsumerProperties!= null && restConsumerProperties.getContext() != null){
+ context = restConsumerProperties.getContext();
+ }
+ return context;
+ }
+
+ public Object sendMonitorRequest(String appId, Class extends EtMonitor> monitorClass, Method m,Object[] params) {
+ String httpContext = getHttpContext(appId);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("http://").append(appId)
+ .append("/").append(httpContext)
+ .append("/").append(RestRibbonMonitorProvider.MONITOR_CONTEXT)
+ .append("/").append(monitorClass.getSimpleName())
+ .append("/").append(m.getName())
+ .append("?");
+
+ int pos = 0;
+ for(Parameter param : m.getParameters()) {
+ if(params[pos] != null) {
+ sb.append(param.getName()).append("=").append(params[pos++]).append("&");
+ }
+ }
+
+ ResponseEntity> exchangeResult = loadBalancedRestTemplate.exchange(sb.toString(), HttpMethod.GET, null, Object.class );
+ if(!exchangeResult.getStatusCode().is2xxSuccessful()){
+ throw new RuntimeException("远程请求发生错误:" + exchangeResult);
+ }
+
+ return exchangeResult.getBody();
+ }
+
private String encodeEasyTransHeader(Map header) {
return new String(Base64.getEncoder().encode(serializer.serialization(header)), StandardCharsets.ISO_8859_1);
}
diff --git a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcProviderImpl.java b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcProviderImpl.java
index 976fd4f..aa0c115 100644
--- a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcProviderImpl.java
+++ b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonEasyTransRpcProviderImpl.java
@@ -172,8 +172,7 @@ public void startService(Class> businessInterface,Map filters) {
this.filters.addAll(filters);
diff --git a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorConsumerFactory.java b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorConsumerFactory.java
new file mode 100644
index 0000000..292a3b7
--- /dev/null
+++ b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorConsumerFactory.java
@@ -0,0 +1,37 @@
+package com.yiqiniu.easytrans.rpc.impl.rest;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.yiqiniu.easytrans.monitor.EtMonitor;
+import com.yiqiniu.easytrans.monitor.MonitorConsumerFactory;
+
+public class RestRibbonMonitorConsumerFactory implements MonitorConsumerFactory {
+
+ private RestRibbonEasyTransRpcConsumerImpl consumer;
+ private ConcurrentHashMap mapMonitor = new ConcurrentHashMap<>();
+
+ public RestRibbonMonitorConsumerFactory(RestRibbonEasyTransRpcConsumerImpl consumer) {
+ super();
+ this.consumer = consumer;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getRemoteProxy(String appId, Class monitorInterface) {
+
+ return (T) mapMonitor.computeIfAbsent(appId + "|" + monitorInterface.getSimpleName() , k->{
+ return (EtMonitor)Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class[] {monitorInterface}, new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ return consumer.sendMonitorRequest(appId, monitorInterface, method, args);
+ }
+ });
+ });
+
+ }
+
+
+}
diff --git a/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorProvider.java b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorProvider.java
new file mode 100644
index 0000000..4382453
--- /dev/null
+++ b/easytrans-rpc-rest-ribbon-starter/src/main/java/com/yiqiniu/easytrans/rpc/impl/rest/RestRibbonMonitorProvider.java
@@ -0,0 +1,88 @@
+package com.yiqiniu.easytrans.rpc.impl.rest;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import com.yiqiniu.easytrans.monitor.EtMonitor;
+import com.yiqiniu.easytrans.util.ReflectUtil;
+
+public class RestRibbonMonitorProvider {
+
+// @Autowired
+// private RestRibbonEasyTransRpcProviderImpl controller;
+
+ public static final String MONITOR_CONTEXT = "_monitors";
+
+ @Autowired
+ private RequestMappingHandlerMapping requestMappingHandlerMapping;
+
+ @Autowired
+ private List etMonitorList;
+
+ @Value("${easytrans.rpc.rest-ribbon.provider.context:" + RestRibbonEasyTransConstants.DEFAULT_URL_CONTEXT + "}")
+ private String rootUrl;
+
+ @PostConstruct
+ public void initHandler() throws NoSuchMethodException, SecurityException {
+
+ Set objectMethods = new HashSet<>(Arrays.asList(Object.class.getMethods()));
+
+ for(EtMonitor monitor : etMonitorList) {
+
+ Class extends EtMonitor> monitorClass = monitor.getClass();
+ Class> markClass = ReflectUtil.getClassWithMark(monitorClass,EtMonitor.class);
+ if(!markClass.isInterface()) {
+ throw new RuntimeException("EtMonitor should mark in interface but not class!");
+ }
+
+ for(Method m : monitor.getClass().getMethods()) {
+
+ if(objectMethods.contains(m)) {
+ continue;
+ }
+
+ Object proxy = Proxy.newProxyInstance(monitorClass.getClassLoader(), new Class[]{markClass}, new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+
+ if(!method.getName().equals(m.getName())) {
+ throw new RuntimeException("Illegal call! " + method.getName());
+ }
+
+ Object result = method.invoke(monitor, args);
+
+ return new ResponseEntity