下面列出了怎么用com.alibaba.dubbo.rpc.Invocation的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testDelegate() throws Exception {
DelegateProviderMetaDataInvoker<Greeting> delegate =
new DelegateProviderMetaDataInvoker<Greeting>(invoker, service);
delegate.getInterface();
Mockito.verify(invoker).getInterface();
delegate.getUrl();
Mockito.verify(invoker).getUrl();
delegate.isAvailable();
Mockito.verify(invoker).isAvailable();
Invocation invocation = Mockito.mock(Invocation.class);
delegate.invoke(invocation);
Mockito.verify(invoker).invoke(invocation);
delegate.destroy();
Mockito.verify(invoker).destroy();
assertThat(delegate.getMetadata(), sameInstance(service));
}
public boolean isAllowable(URL url, Invocation invocation) {
long now = System.currentTimeMillis();
if (now > lastResetTime + interval) {
token.set(rate);
lastResetTime = now;
}
int value = token.get();
boolean flag = false;
while (value > 0 && !flag) {
flag = token.compareAndSet(value, value - 1);
value = token.get();
}
return flag;
}
public static Class<?>[] getParameterTypes(Invocation invocation) {
if (Constants.$INVOKE.equals(invocation.getMethodName())
&& invocation.getArguments() != null
&& invocation.getArguments().length > 1
&& invocation.getArguments()[1] instanceof String[]) {
String[] types = (String[]) invocation.getArguments()[1];
if (types == null) {
return new Class<?>[0];
}
Class<?>[] parameterTypes = new Class<?>[types.length];
for (int i = 0; i < types.length; i++) {
parameterTypes[i] = ReflectUtils.forName(types[0]);
}
return parameterTypes;
}
return invocation.getParameterTypes();
}
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (cacheFactory != null && ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.CACHE_KEY))) {
Cache cache = cacheFactory.getCache(invoker.getUrl().addParameter(Constants.METHOD_KEY, invocation.getMethodName()));
if (cache != null) {
String key = StringUtils.toArgumentString(invocation.getArguments());
if (cache != null && key != null) {
Object value = cache.get(key);
if (value != null) {
return new RpcResult(value);
}
Result result = invoker.invoke(invocation);
if (! result.hasException()) {
cache.put(key, result.getValue());
}
return result;
}
}
}
return invoker.invoke(invocation);
}
@SuppressWarnings("unchecked")
@Test
public void testNonEcho() {
Invocation invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { Enum.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.expect(invocation.getAttachments()).andReturn(null).anyTimes();
EasyMock.replay(invocation);
Invoker<DemoService> invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("High");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = echoFilter.invoke(invoker, invocation);
assertEquals("High", filterResult.getValue());
}
@Test
public void testInvokerNonJsonNonPojoSerialization() {
invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] {String.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.replay(invocation);
invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue(new String[]{"High"});
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = compatibleFilter.invoke(invoker, invocation);
assertArrayEquals(new String[]{"High"}, (String[])filterResult.getValue());
}
@SuppressWarnings("unchecked")
@Test
public void testEcho() {
Invocation invocation = mock(Invocation.class);
given(invocation.getMethodName()).willReturn("$echo");
given(invocation.getParameterTypes()).willReturn(new Class<?>[]{Enum.class});
given(invocation.getArguments()).willReturn(new Object[]{"hello"});
given(invocation.getAttachments()).willReturn(null);
Invoker<DemoService> invoker = mock(Invoker.class);
given(invoker.isAvailable()).willReturn(true);
given(invoker.getInterface()).willReturn(DemoService.class);
RpcResult result = new RpcResult();
result.setValue("High");
given(invoker.invoke(invocation)).willReturn(result);
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
given(invoker.getUrl()).willReturn(url);
Result filterResult = echoFilter.invoke(invoker, invocation);
assertEquals("hello", filterResult.getValue());
}
/**
* Return MockInvoker
* Contract:
* directory.list() will return a list of normal invokers if Constants.INVOCATION_NEED_MOCK is present in invocation, otherwise, a list of mock invokers will return.
* if directory.list() returns more than one mock invoker, only one of them will be used.
* 返回MockInvoker合同:directory.list()将返回一个列表的正常调用器如果常量。调用中存在INVOCATION_NEED_MOCK,否则,将返回一个模拟调用程序列表。如果directory.list()返回多个模拟调用程序,则只使用其中一个。
*
* @param invocation
* @return
*/
private List<Invoker<T>> selectMockInvoker(Invocation invocation) {
List<Invoker<T>> invokers = null;
//TODO generic invoker?
if (invocation instanceof RpcInvocation) {
//Note the implicit contract (although the description is added to the interface declaration, but extensibility is a problem. The practice placed in the attachement needs to be improved)
((RpcInvocation) invocation).setAttachment(Constants.INVOCATION_NEED_MOCK, Boolean.TRUE.toString());
//directory will return a list of normal invokers if Constants.INVOCATION_NEED_MOCK is present in invocation, otherwise, a list of mock invokers will return.
try {
invokers = directory.list(invocation);
} catch (RpcException e) {
if (logger.isInfoEnabled()) {
logger.info("Exception when try to invoke mock. Get mock invokers error for service:"
+ directory.getUrl().getServiceInterface() + ", method:" + invocation.getMethodName()
+ ", will contruct a new mock with 'new MockInvoker()'.", e);
}
}
}
return invokers;
}
@Test
public void testGenericFilter() throws Exception {
MonitorFilter monitorFilter = new MonitorFilter();
monitorFilter.setMonitorFactory(monitorFactory);
Invocation invocation = new RpcInvocation("$invoke", new Class<?>[] { String.class, String[].class, Object[].class }, new Object[] { "xxx", new String[] {}, new Object[] {} } );
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
monitorFilter.invoke(serviceInvoker, invocation);
while (lastStatistics == null) {
Thread.sleep(10);
}
Assert.assertEquals("abc", lastStatistics.getParameter(MonitorService.APPLICATION));
Assert.assertEquals(MonitorService.class.getName(), lastStatistics.getParameter(MonitorService.INTERFACE));
Assert.assertEquals("xxx", lastStatistics.getParameter(MonitorService.METHOD));
Assert.assertEquals(NetUtils.getLocalHost() + ":20880", lastStatistics.getParameter(MonitorService.PROVIDER));
Assert.assertEquals(NetUtils.getLocalHost(), lastStatistics.getAddress());
Assert.assertEquals(null, lastStatistics.getParameter(MonitorService.CONSUMER));
Assert.assertEquals(1, lastStatistics.getParameter(MonitorService.SUCCESS, 0));
Assert.assertEquals(0, lastStatistics.getParameter(MonitorService.FAILURE, 0));
Assert.assertEquals(1, lastStatistics.getParameter(MonitorService.CONCURRENT, 0));
Assert.assertEquals(invocation, lastInvocation);
}
@SuppressWarnings("unchecked")
@Test
public void testNonEcho() {
Invocation invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { Enum.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.expect(invocation.getAttachments()).andReturn(null).anyTimes();
EasyMock.replay(invocation);
Invoker<DemoService> invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("High");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = echoFilter.invoke(invoker, invocation);
assertEquals("High", filterResult.getValue());
}
public Result invoke(final Invocation invocation) throws RpcException {
checkWheatherDestoried();
LoadBalance loadbalance;
List<Invoker<T>> invokers = list(invocation);
if (invokers != null && invokers.size() > 0) {
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
.getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
} else {
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
/**
* 使用loadbalance选择invoker.</br>
* a)先lb选择,如果在selected列表中 或者 不可用且做检验时,进入下一步(重选),否则直接返回</br>
* b)重选验证规则:selected > available .保证重选出的结果尽量不在select中,并且是可用的
*
* @param availablecheck 如果设置true,在选择的时候先选invoker.available == true
* @param selected 已选过的invoker.注意:输入保证不重复
*
*/
protected Invoker<T> select(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {
if (invokers == null || invokers.size() == 0)
return null;
String methodName = invocation == null ? "" : invocation.getMethodName();
boolean sticky = invokers.get(0).getUrl().getMethodParameter(methodName,Constants.CLUSTER_STICKY_KEY, Constants.DEFAULT_CLUSTER_STICKY) ;
{
//ignore overloaded method
if ( stickyInvoker != null && !invokers.contains(stickyInvoker) ){
stickyInvoker = null;
}
//ignore cucurrent problem
if (sticky && stickyInvoker != null && (selected == null || !selected.contains(stickyInvoker))){
if (availablecheck && stickyInvoker.isAvailable()){
return stickyInvoker;
}
}
}
Invoker<T> invoker = doselect(loadbalance, invocation, invokers, selected);
if (sticky){
stickyInvoker = invoker;
}
return invoker;
}
public boolean isAllowable(URL url, Invocation invocation) {
long now = System.currentTimeMillis();
if (now > lastResetTime + interval) {
token.set(rate);
lastResetTime = now;
}
int value = token.get();
boolean flag = false;
while (value > 0 && !flag) {
flag = token.compareAndSet(value, value - 1);
value = token.get();
}
return flag;
}
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size(); // 总个数
int totalWeight = 0; // 总权重
boolean sameWeight = true; // 权重是否都一样
for (int i = 0; i < length; i++) {
int weight = getWeight(invokers.get(i), invocation);
totalWeight += weight; // 累计总权重
if (sameWeight && i > 0
&& weight != getWeight(invokers.get(i - 1), invocation)) {
sameWeight = false; // 计算所有权重是否一样
}
}
if (totalWeight > 0 && ! sameWeight) {
// 如果权重不相同且权重大于0则按总权重数随机
int offset = random.nextInt(totalWeight);
// 并确定随机值落在哪个片断上
for (int i = 0; i < length; i++) {
offset -= getWeight(invokers.get(i), invocation);
if (offset < 0) {
return invokers.get(i);
}
}
}
// 如果权重相同或权重为0则均等随机
return invokers.get(random.nextInt(length));
}
@SuppressWarnings("unchecked")
@Test
public void testEcho() {
Invocation invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("$echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] { Enum.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.expect(invocation.getAttachments()).andReturn(null).anyTimes();
EasyMock.replay(invocation);
Invoker<DemoService> invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue("High");
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = echoFilter.invoke(invoker, invocation);
assertEquals("hello", filterResult.getValue());
}
public Result invoke(final Invocation invocation) throws RpcException {
checkWheatherDestoried();
LoadBalance loadbalance;
List<Invoker<T>> invokers = list(invocation);
if (invokers != null && invokers.size() > 0) {
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()
.getMethodParameter(invocation.getMethodName(),Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
} else {
loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
return doInvoke(invocation, invokers, loadbalance);
}
@Test
public void testInvoke() {
final Invoker invoker = mock(Invoker.class);
when(invoker.getInterface()).thenReturn(DemoService.class);
final Invocation invocation = mock(Invocation.class);
Method method = DemoService.class.getMethods()[0];
when(invocation.getMethodName()).thenReturn(method.getName());
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
final Result result = mock(Result.class);
when(result.hasException()).thenReturn(false);
when(invoker.invoke(invocation)).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
verifyInvocationStructure(invoker, invocation);
return result;
}
});
filter.invoke(invoker, invocation);
verify(invoker).invoke(invocation);
Context context = ContextUtil.getContext();
assertNull(context);
}
@Test
public void testGenericFilter() throws Exception {
MonitorFilter monitorFilter = new MonitorFilter();
monitorFilter.setMonitorFactory(monitorFactory);
Invocation invocation = new RpcInvocation("$invoke", new Class<?>[]{String.class, String[].class, Object[].class}, new Object[]{"xxx", new String[]{}, new Object[]{}});
RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345);
monitorFilter.invoke(serviceInvoker, invocation);
while (lastStatistics == null) {
Thread.sleep(10);
}
Assert.assertEquals("abc", lastStatistics.getParameter(MonitorService.APPLICATION));
Assert.assertEquals(MonitorService.class.getName(), lastStatistics.getParameter(MonitorService.INTERFACE));
Assert.assertEquals("xxx", lastStatistics.getParameter(MonitorService.METHOD));
Assert.assertEquals(NetUtils.getLocalHost() + ":20880", lastStatistics.getParameter(MonitorService.PROVIDER));
Assert.assertEquals(NetUtils.getLocalHost(), lastStatistics.getAddress());
Assert.assertEquals(null, lastStatistics.getParameter(MonitorService.CONSUMER));
Assert.assertEquals(1, lastStatistics.getParameter(MonitorService.SUCCESS, 0));
Assert.assertEquals(0, lastStatistics.getParameter(MonitorService.FAILURE, 0));
Assert.assertEquals(1, lastStatistics.getParameter(MonitorService.CONCURRENT, 0));
Assert.assertEquals(invocation, lastInvocation);
}
@Test
public void testInvokerNonJsonNonPojoSerialization() {
invocation = EasyMock.createMock(Invocation.class);
EasyMock.expect(invocation.getMethodName()).andReturn("echo").anyTimes();
EasyMock.expect(invocation.getParameterTypes()).andReturn(new Class<?>[] {String.class }).anyTimes();
EasyMock.expect(invocation.getArguments()).andReturn(new Object[] { "hello" }).anyTimes();
EasyMock.replay(invocation);
invoker = EasyMock.createMock(Invoker.class);
EasyMock.expect(invoker.isAvailable()).andReturn(true).anyTimes();
EasyMock.expect(invoker.getInterface()).andReturn(DemoService.class).anyTimes();
RpcResult result = new RpcResult();
result.setValue(new String[]{"High"});
EasyMock.expect(invoker.invoke(invocation)).andReturn(result).anyTimes();
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
EasyMock.expect(invoker.getUrl()).andReturn(url).anyTimes();
EasyMock.replay(invoker);
Result filterResult = compatibleFilter.invoke(invoker, invocation);
assertArrayEquals(new String[]{"High"}, (String[])filterResult.getValue());
}
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getContext()
.setInvoker(invoker)
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0)
.setRemoteAddress(invoker.getUrl().getHost(),
invoker.getUrl().getPort());
if (invocation instanceof RpcInvocation) {
((RpcInvocation)invocation).setInvoker(invoker);
}
try {
return invoker.invoke(invocation);
} finally {
RpcContext.getContext().clearAttachments();
}
}
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if (validation != null && ! invocation.getMethodName().startsWith("$")
&& ConfigUtils.isNotEmpty(invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.VALIDATION_KEY))) {
try {
Validator validator = validation.getValidator(invoker.getUrl());
if (validator != null) {
validator.validate(invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
}
} catch (RpcException e) {
throw e;
} catch (Throwable t) {
throw new RpcException(t.getMessage(), t);
}
}
return invoker.invoke(invocation);
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getContext()
.setInvoker(invoker)
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0)
.setRemoteAddress(invoker.getUrl().getHost(),
invoker.getUrl().getPort());
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
try {
// com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper.buildInvokerChain com.alibaba.dubbo.rpc.Invoker.invoke()
RpcResult result = (RpcResult) invoker.invoke(invocation);
RpcContext.getServerContext().setAttachments(result.getAttachments());
return result;
} finally {
RpcContext.getContext().clearAttachments();
}
}
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
if (invokers == null || invokers.isEmpty())
return null;
if (invokers.size() == 1)
return invokers.get(0);
return doSelect(invokers, url, invocation);
}
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
Map<String, String> attachments = invocation.getAttachments();
if (attachments != null) {
attachments = new HashMap<String, String>(attachments);
attachments.remove(Constants.PATH_KEY);
attachments.remove(Constants.GROUP_KEY);
attachments.remove(Constants.VERSION_KEY);
attachments.remove(Constants.DUBBO_VERSION_KEY);
attachments.remove(Constants.TOKEN_KEY);
attachments.remove(Constants.TIMEOUT_KEY);
}
RpcContext.getContext()
.setInvoker(invoker)
.setInvocation(invocation)
// .setAttachments(attachments) // modified by lishen
.setLocalAddress(invoker.getUrl().getHost(),
invoker.getUrl().getPort());
// modified by lishen
if (attachments != null) {
if (RpcContext.getContext().getAttachments() != null) {
RpcContext.getContext().getAttachments().putAll(attachments);
} else {
RpcContext.getContext().setAttachments(attachments);
}
}
if (invocation instanceof RpcInvocation) {
((RpcInvocation)invocation).setInvoker(invoker);
}
try {
return invoker.invoke(invocation);
} finally {
RpcContext.removeContext();
}
}
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException, RemotingException {
if (RpcContext.getContext().isProviderSide()) {
return this.providerInvoke(invoker, invocation);
} else {
return this.consumerInvoke(invoker, invocation);
}
}
private static boolean isAttachInvocationId(URL url , Invocation invocation) {
String value = url.getMethodParameter(invocation.getMethodName(), Constants.AUTO_ATTACH_INVOCATIONID_KEY);
if ( value == null ) {
//异步操作默认添加invocationid
return isAsync(url,invocation) ;
} else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
//设置为添加,则一定添加
return true;
} else {
//value为false时,不添加
return false;
}
}
@Before
public void setUp() throws Exception {
directory = EasyMock.createMock( Directory.class );
firstInvoker = EasyMock.createMock( Invoker.class );
secondInvoker = EasyMock.createMock( Invoker.class );
invocation = EasyMock.createMock( Invocation.class );
}
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), Constants.MOCK_KEY, Boolean.FALSE.toString()).trim();
if (value.length() == 0 || value.equalsIgnoreCase("false")){
//no mock
result = this.invoker.invoke(invocation);
} else if (value.startsWith("force")) {
if (logger.isWarnEnabled()) {
logger.info("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + directory.getUrl());
}
//force:direct mock
result = doMockInvoke(invocation, null);
} else {
//fail-mock
try {
result = this.invoker.invoke(invocation);
}catch (RpcException e) {
if (e.isBiz()) {
throw e;
} else {
if (logger.isWarnEnabled()) {
logger.info("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + directory.getUrl(), e);
}
result = doMockInvoke(invocation, e);
}
}
}
return result;
}
public static Object[] getArguments(Invocation invocation) {
if (Constants.$INVOKE.equals(invocation.getMethodName())
&& invocation.getArguments() != null
&& invocation.getArguments().length > 2
&& invocation.getArguments()[2] instanceof Object[]) {
return (Object[]) invocation.getArguments()[2];
}
return invocation.getArguments();
}
@SuppressWarnings("unchecked")
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
try {
List<Invoker<T>> invokersCopy = new ArrayList<Invoker<T>>(invokers);
Compilable compilable = (Compilable) engine;
Bindings bindings = engine.createBindings();
bindings.put("invokers", invokersCopy);
bindings.put("invocation", invocation);
bindings.put("context", RpcContext.getContext());
CompiledScript function = compilable.compile(rule);
Object obj = function.eval(bindings);
if (obj instanceof Invoker[]) {
invokersCopy = Arrays.asList((Invoker<T>[]) obj);
} else if (obj instanceof Object[]) {
invokersCopy = new ArrayList<Invoker<T>>();
for (Object inv : (Object[]) obj) {
invokersCopy.add((Invoker<T>)inv);
}
} else {
invokersCopy = (List<Invoker<T>>) obj;
}
return invokersCopy;
} catch (ScriptException e) {
//fail then ignore rule .invokers.
logger.error("route error , rule has been ignored. rule: " + rule + ", method:" + invocation.getMethodName() + ", url: " + RpcContext.getContext().getUrl(), e);
return invokers;
}
}