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

com.taobao.api.internal.toplink.endpoint.Endpoint Maven / Gradle / Ivy

The newest version!
package com.taobao.api.internal.toplink.endpoint;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.taobao.api.internal.toplink.DefaultLoggerFactory;
import com.taobao.api.internal.toplink.LinkException;
import com.taobao.api.internal.toplink.Logger;
import com.taobao.api.internal.toplink.LoggerFactory;
import com.taobao.api.internal.toplink.Text;
import com.taobao.api.internal.toplink.channel.ChannelException;
import com.taobao.api.internal.toplink.channel.ChannelSender;
import com.taobao.api.internal.toplink.channel.ClientChannelSelector;
import com.taobao.api.internal.toplink.channel.ClientChannelSharedSelector;
import com.taobao.api.internal.toplink.channel.ServerChannel;
import com.taobao.api.internal.toplink.schedule.Scheduler;

// Abstract network model
// https://docs.google.com/drawings/d/1PRfzMVNGE4NKkpD9A_-QlH2PV47MFumZX8LbCwhzpQg/edit
public class Endpoint {
	protected static int TIMOUT = 5000;
	private Logger logger;
	private Identity identity;
	private List serverChannels;
	private ClientChannelSelector channelSelector;
	private EndpointChannelHandler channelHandler;
	private MessageHandler messageHandler;

	// in/out endpoints
	private List connected;

	public Endpoint(Identity identity) {
		this(DefaultLoggerFactory.getDefault(), identity);
	}

	public Endpoint(LoggerFactory loggerFactory, Identity identity) {
		this.serverChannels = new ArrayList();
		this.connected = new ArrayList();
		this.logger = loggerFactory.create(this);
		this.identity = identity;
		this.setClientChannelSelector(new ClientChannelSharedSelector(loggerFactory));
		this.setChannelHandler(new EndpointChannelHandler(loggerFactory));

		if (this.identity == null)
			throw new NullPointerException("identity");
	}

	public Identity getIdentity() {
		return this.identity;
	}

	public void setMessageHandler(MessageHandler handler) {
		this.messageHandler = handler;
	}

	public MessageHandler getMessageHandler() {
		return this.messageHandler;
	}

	public void setChannelHandler(EndpointChannelHandler channelHandler) {
		this.channelHandler = channelHandler;
		this.channelHandler.setEndpoint(this);
		for (ServerChannel channel : this.serverChannels)
			channel.setChannelHandler(this.channelHandler);
	}

	public void setClientChannelSelector(ClientChannelSelector selector) {
		this.channelSelector = selector;
	}

	public void setScheduler(Scheduler scheduler) {
		this.channelHandler.setScheduler(scheduler);
	}

	public void bind(ServerChannel channel) {
		channel.setChannelHandler(this.channelHandler);
		channel.run();
		this.serverChannels.add(channel);
	}

	public void unbindAll() {
		for (ServerChannel channel : this.serverChannels) {
			try {
				channel.stop();
			} catch (Exception e) {
				this.logger.error(Text.E_UNBIND_ERROR, e);
			}
		}
		this.serverChannels.clear();
	}

	public Iterator getConnected() {
		return this.connected.iterator();
	}

	public synchronized EndpointProxy getEndpoint(Identity target, URI uri) throws LinkException {
		return this.getEndpoint(target, uri, null);
	}

	// connect to target via special uri
	public synchronized EndpointProxy getEndpoint(
			Identity target, URI uri, Map extras) throws LinkException {
		// connect message
		Message msg = new Message();
		msg.messageType = MessageType.CONNECT;
		Map content = new HashMap();
		this.identity.render(content);
		// pass extra data
		if (extras != null)
			content.putAll(extras);
		msg.content = content;

		EndpointProxy e = this.getEndpoint(target);
		// always clear, cached proxy will have broken channel
		e.remove(uri);
		// always reget channel, make sure it's valid
		ClientChannelWrapper channel = new ClientChannelWrapper(
				// set default version on this channel
				this.channelSelector.getChannel(uri), msg.protocolVersion);
		channel.setChannelHandler(this.channelHandler);
		// send connect
		this.sendAndWait(e, channel, msg, TIMOUT);
		e.add(channel);
		return e;
	}

	public synchronized EndpointProxy getEndpoint(Identity target) throws LinkException {
		if (target.equals(this.identity))
			throw new LinkException(Text.E_ID_DUPLICATE);

		for (EndpointProxy e : this.connected) {
			if (e.getIdentity() != null &&
					e.getIdentity().equals(target))
				return e;
		}
		EndpointProxy e = this.createProxy(target.toString());
		e.setIdentity(target);
		return e;
	}

	protected void send(ChannelSender sender, Message message) throws ChannelException {
		this.channelHandler.pending(message, sender);
	}

	protected Map sendAndWait(EndpointProxy e,
			ChannelSender sender,
			Message message,
			int timeout) throws LinkException {
		SendCallback callback = new SendCallback(e);
		this.channelHandler.pending(message, sender, callback);
		try {
			callback.waitReturn(timeout);
		} finally {
			this.channelHandler.cancel(callback);
		}
		if (callback.getError() != null)
			throw callback.getError();
		return callback.getReturn();
	}

	private EndpointProxy createProxy(String reason) {
		EndpointProxy e = new EndpointProxy(this);
		this.connected.add(e);
		if (this.logger.isDebugEnabled())
			this.logger.debug(Text.E_CREATE_NEW + ": " + reason);
		return e;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy