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

rpc.turbo.client.TurboClient Maven / Gradle / Ivy

The newest version!
package rpc.turbo.client;

import java.io.Closeable;
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.channel.EventLoopGroup;
import rpc.turbo.common.EventLoopGroupHolder;
import rpc.turbo.config.HostPort;
import rpc.turbo.config.client.AppConfig;
import rpc.turbo.config.client.ClientConfig;
import rpc.turbo.filter.RpcClientFilter;
import rpc.turbo.invoke.FailoverInvokerFactory;
import rpc.turbo.invoke.InvokerUtils;
import rpc.turbo.remote.RemoteException;
import rpc.turbo.remote.RemoteInterface;
import rpc.turbo.remote.RemoteServiceFactory;
import rpc.turbo.transport.client.App;

/**
 * 
 * @author Hank
 *
 */
public final class TurboClient implements Closeable {
	private static final Log logger = LogFactory.getLog(TurboClient.class);

	private final FailoverInvokerFactory failoverInvokerFactory = new FailoverInvokerFactory();
	private final RemoteServiceFactory remoteServiceFactory = new RemoteServiceFactory(failoverInvokerFactory);
	private final ConcurrentHashMap appMap = new ConcurrentHashMap<>();
	private final EventLoopGroup eventLoopGroup;
	private final CopyOnWriteArrayList filters = new CopyOnWriteArrayList<>();

	public TurboClient() {
		this(new ClientConfig());
	}

	public TurboClient(String resourceName) {
		this(ClientConfig.parse(resourceName));
	}

	public TurboClient(ClientConfig clientConfig) {
		eventLoopGroup = EventLoopGroupHolder.get();

		if (clientConfig != null && clientConfig.getAppConfigList() != null) {
			clientConfig.getAppConfigList().forEach(appConfig -> addConnect(appConfig));
		}
	}

	public void addConnect(AppConfig appConfig) {
		Objects.requireNonNull(appConfig, "appConfig");

		try {
			App _app = new App(eventLoopGroup, appConfig, filters);
			appMap.put(_app, Boolean.TRUE);
		} catch (Exception e) {
			throw new RemoteException(e);
		}
	}

	/**
	 * 手动建立连接
	 * 
	 * @param group
	 * @param hostPorts
	 */
	public void addConnect(String group, String app, HostPort... hostPorts) {
		Objects.requireNonNull(group, "group");
		Objects.requireNonNull(app, "app");
		Objects.requireNonNull(hostPorts, "hostPorts");

		try {
			AppConfig appConfig = new AppConfig();
			appConfig.setGroup(group);
			appConfig.setApp(app);

			App _app = new App(eventLoopGroup, appConfig, filters);
			_app.setConnect(hostPorts);
			appMap.put(_app, Boolean.TRUE);
		} catch (Exception e) {
			throw new RemoteException(e);
		}
	}

	/**
	 * 注册一个远程服务
	 * 
	 * @param group
	 * @param app
	 * @param clazz
	 * @param failover
	 */
	public  void register(String group, String app, Class clazz, Object failover) {
		T service = remoteServiceFactory.getService(clazz);

		if (service != null) {
			return;
		}

		Objects.requireNonNull(group, "group");
		Objects.requireNonNull(app, "app");

		Optional appOptional = appMap//
				.keySet()//
				.stream()//
				.filter(v -> v.group.equals(group))//
				.filter(v -> v.app.equals(app))//
				.filter(v -> v.isSupport(clazz))//
				.findFirst();

		if (!appOptional.isPresent()) {
			throw new RemoteException(
					"not support this service, " + InvokerUtils.getServiceClassName(group, app, clazz));
		}

		App application = appOptional.get();

		try {
			remoteServiceFactory.register(application, clazz);
			remoteServiceFactory.setFailover(application, clazz, service, failover);
		} catch (Exception e) {
			throw new RemoteException(e);
		}
	}

	/**
	 * 注册一个远程服务
	 * 
	 * @param clazz
	 */
	public  void register(Class clazz) {
		Objects.requireNonNull(clazz, "clazz");

		T service = remoteServiceFactory.getService(clazz);

		if (service != null) {
			return;
		}

		Optional appOptional = appMap//
				.keySet()//
				.stream()//
				.filter(v -> v.isSupport(clazz))//
				.findFirst();

		if (!appOptional.isPresent()) {
			throw new RemoteException("not support this service, " + clazz.getName());
		}

		App app = appOptional.get();

		try {
			remoteServiceFactory.register(app, clazz);
		} catch (Exception e) {
			throw new RemoteException(e);
		}
	}

	/**
	 * 设置失败回退方法
	 * 
	 * @param clazz
	 * @param failover
	 */
	public  void setFailover(Class clazz, Object failover) {
		Objects.requireNonNull(clazz, "clazz");

		T service = remoteServiceFactory.getService(clazz);

		if (service == null) {
			throw new RemoteException("not register this service, " + clazz.getName());
		}

		try {
			App app = ((RemoteInterface) service).getApp();
			remoteServiceFactory.setFailover(app, clazz, service, failover);
		} catch (Exception e) {
			throw new RemoteException(e);
		}
	}

	/**
	 * 获取一个远程服务,必须先注册 :
* {@link #register(Class)} or {@link #register(String, String, Class, Object)} * * @param clazz * @return */ public T getService(Class clazz) { return remoteServiceFactory.getService(clazz); } /** * 添加过滤器到最前面,最前面的会被最先执行 * * @param filter */ public void addFirst(RpcClientFilter filter) { filters.add(0, filter); } /** * 添加过滤器到最后面,最后面的会被最后执行 * * @param filter */ public void addLast(RpcClientFilter filter) { filters.add(filter); } @Override public void close() throws IOException { appMap.forEachKey(4, app -> { try { app.close(); } catch (IOException e) { if (logger.isWarnEnabled()) { logger.warn("client close error", e); } } }); EventLoopGroupHolder.release(eventLoopGroup); appMap.clear(); remoteServiceFactory.close(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy