All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.dubbo.rpc.protocol.AbstractInvoker Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed 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 com.alibaba.dubbo.rpc.protocol;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.Version;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcInvocation;
import com.alibaba.dubbo.rpc.RpcResult;
import com.alibaba.dubbo.rpc.support.RpcUtils;

import lombok.extern.slf4j.Slf4j;
import net.jahhan.common.extension.constant.JahhanErrorCode;
import net.jahhan.exception.JahhanException;

/**
 * AbstractInvoker.
 * 
 * @author qian.lei
 * @author william.liangf
 */
@Slf4j
public abstract class AbstractInvoker implements Invoker {

	private final Class type;

	private final URL url;

	private final Map attachment;

	private volatile boolean available = true;

	private AtomicBoolean destroyed = new AtomicBoolean(false);

	public AbstractInvoker(Class type, URL url) {
		this(type, url, (Map) null);
	}

	public AbstractInvoker(Class type, URL url, String[] keys) {
		this(type, url, convertAttachment(url, keys));
	}

	public AbstractInvoker(Class type, URL url, Map attachment) {
		if (type == null)
			throw new IllegalArgumentException("service type == null");
		if (url == null)
			throw new IllegalArgumentException("service url == null");
		this.type = type;
		this.url = url;
		this.attachment = attachment == null ? null : Collections.unmodifiableMap(attachment);
	}

	private static Map convertAttachment(URL url, String[] keys) {
		if (keys == null || keys.length == 0) {
			return null;
		}
		Map attachment = new HashMap();
		for (String key : keys) {
			String value = url.getParameter(key);
			if (value != null && value.length() > 0) {
				attachment.put(key, value);
			}
		}
		return attachment;
	}

	public Class getInterface() {
		return type;
	}

	public URL getUrl() {
		return url;
	}

	public boolean isAvailable() {
		return available;
	}

	protected void setAvailable(boolean available) {
		this.available = available;
	}

	public void destroy() {
		if (!destroyed.compareAndSet(false, true)) {
			return;
		}
		setAvailable(false);
	}

	public boolean isDestroyed() {
		return destroyed.get();
	}

	public String toString() {
		return getInterface() + " -> " + (getUrl() == null ? "" : getUrl().toString());
	}

	public Result invoke(Invocation inv) throws JahhanException {
		if (destroyed.get()) {
			throw new JahhanException("Rpc invoker for service " + this + " on consumer " + NetUtils.getLocalHost()
					+ " use dubbo version " + Version.getVersion() + " is DESTROYED, can not be invoked any more!");
		}
		RpcInvocation invocation = (RpcInvocation) inv;
		invocation.setInvoker(this);
		if (attachment != null && attachment.size() > 0) {
			invocation.addAttachmentsIfAbsent(attachment);
		}
		Map context = RpcContext.getContext().getAttachments();
		if (context != null) {
			invocation.addAttachmentsIfAbsent(context);
		}
		if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) {
			invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
		}
		RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);

		try {
			return doInvoke(invocation);
		} catch (InvocationTargetException e) { // biz exception
			Throwable te = e.getTargetException();
			if (te == null) {
				return new RpcResult(e);
			} else {
				if (te instanceof JahhanException) {
					((JahhanException) te).setCode(JahhanErrorCode.BIZ_EXCEPTION);
				}
				return new RpcResult(te);
			}
		} catch (JahhanException e) {
			if (e.isBiz()) {
				return new RpcResult(e);
			} else {
				throw e;
			}
		} catch (Throwable e) {
			return new RpcResult(e);
		}
	}

	protected abstract Result doInvoke(Invocation invocation) throws Throwable;

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy