CalvinKirs
4 years ago
16 changed files with 464 additions and 0 deletions
@ -0,0 +1,12 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
|
||||
/** |
||||
* Invoker |
||||
*/ |
||||
public interface Invoker { |
||||
|
||||
RpcResponse invoke(RpcRequest req) throws Throwable; |
||||
} |
@ -0,0 +1,49 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.client; |
||||
|
||||
import net.bytebuddy.implementation.bind.annotation.AllArguments; |
||||
import net.bytebuddy.implementation.bind.annotation.Origin; |
||||
import net.bytebuddy.implementation.bind.annotation.RuntimeType; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
import org.apache.dolphinscheduler.remote.rpc.filter.FilterChain; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.util.UUID; |
||||
|
||||
/** |
||||
* ConsumerInterceptor |
||||
*/ |
||||
public class ConsumerInterceptor { |
||||
|
||||
private Invoker invoker; |
||||
|
||||
|
||||
private FilterChain filterChain; |
||||
|
||||
public ConsumerInterceptor(Invoker invoker) { |
||||
this.filterChain = new FilterChain(invoker); |
||||
this.invoker = this.filterChain.buildFilterChain(); |
||||
} |
||||
|
||||
|
||||
@RuntimeType |
||||
public Object intercept(@AllArguments Object[] args, @Origin Method method) throws Throwable { |
||||
RpcRequest request = buildReq(args, method); |
||||
//todo
|
||||
System.out.println(invoker.invoke(request)); |
||||
return null; |
||||
|
||||
} |
||||
|
||||
private RpcRequest buildReq(Object[] args, Method method) { |
||||
RpcRequest request = new RpcRequest(); |
||||
request.setRequestId(UUID.randomUUID().toString()); |
||||
request.setClassName(method.getDeclaringClass().getName()); |
||||
request.setMethodName(method.getName()); |
||||
request.setParameterTypes(method.getParameterTypes()); |
||||
request.setParameters(args); |
||||
return request; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,18 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.client; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-09 15:27 |
||||
*/ |
||||
public class ConsumerInvoker implements Invoker { |
||||
@Override |
||||
public RpcResponse invoke(RpcRequest req) throws Throwable { |
||||
|
||||
System.out.println(req.getRequestId()+"kris"); |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.client; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-09 10:58 |
||||
*/ |
||||
public interface IRpcClient { |
||||
|
||||
|
||||
<T> T create(Class<T> clazz) throws Exception; |
||||
|
||||
} |
@ -0,0 +1,33 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.client; |
||||
|
||||
import net.bytebuddy.ByteBuddy; |
||||
import net.bytebuddy.implementation.MethodDelegation; |
||||
import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; |
||||
|
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-09 10:59 |
||||
*/ |
||||
public class RpcClient implements IRpcClient{ |
||||
|
||||
private ConcurrentHashMap<String,Object> classMap=new ConcurrentHashMap<>(); |
||||
|
||||
|
||||
@Override |
||||
public <T> T create(Class<T> clazz) throws Exception { |
||||
if(!classMap.containsKey(clazz.getName())){ |
||||
T proxy = new ByteBuddy() |
||||
.subclass(clazz) |
||||
.method(isDeclaredBy(clazz)).intercept(MethodDelegation.to(new ConsumerInterceptor(new ConsumerInvoker()))) |
||||
.make() |
||||
.load(getClass().getClassLoader()) |
||||
.getLoaded() |
||||
.getDeclaredConstructor().newInstance(); |
||||
|
||||
classMap.putIfAbsent(clazz.getName(),proxy); |
||||
} |
||||
return (T) classMap.get(clazz.getName()); |
||||
} |
||||
} |
@ -0,0 +1,54 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.common; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-09 13:21 |
||||
*/ |
||||
public class RpcRequest { |
||||
|
||||
private String requestId; |
||||
private String className; |
||||
private String methodName; |
||||
private Class<?>[] parameterTypes; |
||||
private Object[] parameters; |
||||
|
||||
public String getRequestId() { |
||||
return requestId; |
||||
} |
||||
|
||||
public void setRequestId(String requestId) { |
||||
this.requestId = requestId; |
||||
} |
||||
|
||||
public String getClassName() { |
||||
return className; |
||||
} |
||||
|
||||
public void setClassName(String className) { |
||||
this.className = className; |
||||
} |
||||
|
||||
public String getMethodName() { |
||||
return methodName; |
||||
} |
||||
|
||||
public void setMethodName(String methodName) { |
||||
this.methodName = methodName; |
||||
} |
||||
|
||||
public Class<?>[] getParameterTypes() { |
||||
return parameterTypes; |
||||
} |
||||
|
||||
public void setParameterTypes(Class<?>[] parameterTypes) { |
||||
this.parameterTypes = parameterTypes; |
||||
} |
||||
|
||||
public Object[] getParameters() { |
||||
return parameters; |
||||
} |
||||
|
||||
public void setParameters(Object[] parameters) { |
||||
this.parameters = parameters; |
||||
} |
||||
} |
@ -0,0 +1,44 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.common; |
||||
|
||||
/** |
||||
* RpcResponse |
||||
*/ |
||||
public class RpcResponse { |
||||
|
||||
private String requestId; |
||||
private String msg; |
||||
private Object result; |
||||
private Byte status; |
||||
|
||||
public String getRequestId() { |
||||
return requestId; |
||||
} |
||||
|
||||
public void setRequestId(String requestId) { |
||||
this.requestId = requestId; |
||||
} |
||||
|
||||
public String getMsg() { |
||||
return msg; |
||||
} |
||||
|
||||
public void setMsg(String msg) { |
||||
this.msg = msg; |
||||
} |
||||
|
||||
public Object getResult() { |
||||
return result; |
||||
} |
||||
|
||||
public void setResult(Object result) { |
||||
this.result = result; |
||||
} |
||||
|
||||
public Byte getStatus() { |
||||
return status; |
||||
} |
||||
|
||||
public void setStatus(Byte status) { |
||||
this.status = status; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
||||
|
||||
public interface Filter { |
||||
|
||||
|
||||
RpcResponse filter(Invoker invoker, RpcRequest req) throws Throwable; |
||||
} |
@ -0,0 +1,38 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* FilterChain |
||||
*/ |
||||
public class FilterChain { |
||||
|
||||
|
||||
private List<Filter> filters; |
||||
|
||||
private Invoker invoker; |
||||
|
||||
|
||||
public FilterChain(List<Filter> filters, Invoker invoker) { |
||||
this.filters = filters; |
||||
this.invoker = invoker; |
||||
} |
||||
|
||||
public FilterChain(Invoker invoker) { |
||||
this(LoaderFilters.create().getFilters(), invoker); |
||||
} |
||||
|
||||
public Invoker buildFilterChain() { |
||||
// 最后一个
|
||||
Invoker last = invoker; |
||||
|
||||
for (int i = filters.size() - 1; i >= 0; i--) { |
||||
last = new FilterWrapper(filters.get(i), last); |
||||
} |
||||
// 第一个
|
||||
return last; |
||||
|
||||
} |
||||
} |
@ -0,0 +1,32 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-11 11:48 |
||||
*/ |
||||
public class FilterWrapper implements Invoker { |
||||
|
||||
|
||||
private Filter next; |
||||
|
||||
private Invoker invoker; |
||||
|
||||
|
||||
public FilterWrapper(Filter next, Invoker invoker) { |
||||
this.next = next; |
||||
this.invoker = invoker; |
||||
} |
||||
|
||||
@Override |
||||
public RpcResponse invoke(RpcRequest args) throws Throwable { |
||||
if (next != null) { |
||||
return next.filter(invoker, args); |
||||
} else { |
||||
return invoker.invoke(args); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* LoaderFilters |
||||
*/ |
||||
public class LoaderFilters { |
||||
|
||||
|
||||
private List<Filter> filterList = new ArrayList<>(); |
||||
|
||||
private LoaderFilters() { |
||||
} |
||||
|
||||
public static LoaderFilters create() { |
||||
|
||||
return new LoaderFilters(); |
||||
} |
||||
|
||||
public List<Filter> getFilters() { |
||||
filterList.add(SelectorFilter.getInstance()); |
||||
return filterList; |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
||||
|
||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
|
||||
/** |
||||
* SelectorFilter |
||||
*/ |
||||
public class SelectorFilter implements Filter { |
||||
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SelectorFilter.class); |
||||
|
||||
|
||||
private SelectorFilter selectorFilter = SelectorFilter.getInstance(); |
||||
|
||||
public static SelectorFilter getInstance() { |
||||
return SelectorFilterInner.INSTANCE; |
||||
} |
||||
|
||||
|
||||
private static class SelectorFilterInner { |
||||
|
||||
private static final SelectorFilter INSTANCE = new SelectorFilter(); |
||||
} |
||||
|
||||
private SelectorFilter() { |
||||
} |
||||
|
||||
@Override |
||||
public RpcResponse filter(Invoker invoker, RpcRequest req) throws Throwable { |
||||
RpcResponse rsp = new RpcResponse(); |
||||
rsp.setMsg("ms"); |
||||
return rsp; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
||||
|
||||
import org.apache.dolphinscheduler.common.utils.CollectionUtils; |
||||
|
||||
import java.util.Collection; |
||||
|
||||
/** |
||||
* AbstractSelector |
||||
*/ |
||||
public abstract class AbstractSelector<T> implements Selector<T>{ |
||||
@Override |
||||
public T select(Collection<T> source) { |
||||
|
||||
if (CollectionUtils.isEmpty(source)) { |
||||
throw new IllegalArgumentException("Empty source."); |
||||
} |
||||
|
||||
/** |
||||
* if only one , return directly |
||||
*/ |
||||
if (source.size() == 1) { |
||||
return (T)source.toArray()[0]; |
||||
} |
||||
return doSelect(source); |
||||
} |
||||
|
||||
protected abstract T doSelect(Collection<T> source); |
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
||||
|
||||
import org.apache.dolphinscheduler.remote.utils.Host; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
import java.util.concurrent.ThreadLocalRandom; |
||||
|
||||
/** |
||||
* @author jiangli |
||||
* @date 2021-01-11 12:00 |
||||
*/ |
||||
public class RandomSelector extends AbstractSelector<Host> { |
||||
|
||||
@Override |
||||
public Host doSelect(final Collection<Host> source) { |
||||
|
||||
List<Host> hosts = new ArrayList<>(source); |
||||
int size = hosts.size(); |
||||
int[] weights = new int[size]; |
||||
int totalWeight = 0; |
||||
int index = 0; |
||||
|
||||
for (Host host : hosts) { |
||||
totalWeight += host.getWeight(); |
||||
weights[index] = host.getWeight(); |
||||
index++; |
||||
} |
||||
|
||||
if (totalWeight > 0) { |
||||
int offset = ThreadLocalRandom.current().nextInt(totalWeight); |
||||
|
||||
for (int i = 0; i < size; i++) { |
||||
offset -= weights[i]; |
||||
if (offset < 0) { |
||||
return hosts.get(i); |
||||
} |
||||
} |
||||
} |
||||
return hosts.get(ThreadLocalRandom.current().nextInt(size)); |
||||
} |
||||
|
||||
} |
||||
|
@ -0,0 +1,16 @@
|
||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
||||
|
||||
import java.util.Collection; |
||||
|
||||
/** |
||||
* Selector |
||||
*/ |
||||
public interface Selector<T> { |
||||
|
||||
/** |
||||
* select |
||||
* @param source source |
||||
* @return T |
||||
*/ |
||||
T select(Collection<T> source); |
||||
} |
Loading…
Reference in new issue