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

io.zbus.mq.MqClient Maven / Gradle / Ivy

package io.zbus.mq;

import java.io.IOException;
import java.util.List;

import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import io.zbus.kit.JsonKit;
import io.zbus.mq.Protocol.ConsumeGroupInfo;
import io.zbus.mq.Protocol.ServerInfo;
import io.zbus.mq.Protocol.TopicInfo;
import io.zbus.mq.Protocol.TrackerInfo;
import io.zbus.mq.server.MqServer;
import io.zbus.transport.CodecInitializer;
import io.zbus.transport.CompositeClient;
import io.zbus.transport.EventLoop;
import io.zbus.transport.ResultCallback;
import io.zbus.transport.ServerAddress;
import io.zbus.transport.inproc.InProcClient;
import io.zbus.transport.tcp.TcpClient;
import io.zbus.transport.tcp.TcpClient.HeartbeatMessageBuilder;
 

public class MqClient extends CompositeClient{         
	protected String token;      
	protected int invokeTimeout = 3000;
	protected int heartbeatInterval = 60000; //60s
	
	public MqClient(String address, final EventLoop loop){
		ServerAddress serverAddress = new ServerAddress(address);
		buildSupport(serverAddress, loop, heartbeatInterval);
	}   
	
	public MqClient(String address, final EventLoop loop, int heartbeatInterval){
		ServerAddress serverAddress = new ServerAddress(address);
		buildSupport(serverAddress, loop, heartbeatInterval);
	}
	
	/**
	 * In-Process MqClient, optimized for speed.
	 * 
	 * @param mqServer MqServer instance in the process, no need to start 
	 */
	public MqClient(MqServer mqServer) {
		ServerAddress serverAddress = new ServerAddress();
		serverAddress.setServer(mqServer);
		
		buildSupport(serverAddress, null, heartbeatInterval);
	} 
	
	public MqClient(ServerAddress serverAddress, final EventLoop loop){  
		buildSupport(serverAddress, loop, heartbeatInterval);
	}
	
	public MqClient(ServerAddress serverAddress, final EventLoop loop, int heartbeatInterval){  
		buildSupport(serverAddress, loop, heartbeatInterval);
	}
	
	private void buildSupport(ServerAddress serverAddress, final EventLoop loop, int heartbeatInterval){
		this.token = serverAddress.getToken();
		if(serverAddress.server != null){
			support = new InProcClient(serverAddress.server);
			return;
		} 
		String address = serverAddress.address;
		if(address == null){
			throw new IllegalArgumentException("ServerAddress missing address property");
		}
		
		if (address.startsWith("ipc://")) {
			throw new IllegalArgumentException("IPC not implemented yet!");
			//TODO IPC client support
		}
		
		//default to TCP 
		if(address.startsWith("tcp://")){
			serverAddress.address = address.substring("tcp://".length());
		}
			
		TcpClient tcp = new TcpClient(serverAddress, loop);
		support = tcp;
		tcp.codec(new CodecInitializer() {
			@Override
			public void initPipeline(List p) {
				p.add(new HttpRequestEncoder()); 
				p.add(new HttpResponseDecoder());  
				p.add(new HttpObjectAggregator(loop.getPackageSizeLimit()));
				p.add(new io.zbus.transport.http.MessageCodec());
				p.add(new io.zbus.mq.MessageCodec());
			}
		}); 
		
		tcp.startHeartbeat(heartbeatInterval, new HeartbeatMessageBuilder() { 
			@Override
			public Message build() { 
				Message hbt = new Message();
				hbt.setCommand(Message.HEARTBEAT);
				return hbt;
			}
		});  
	}
	
	
	public void setInvokeTimeout(int invokeTimeout) {
		this.invokeTimeout = invokeTimeout;
	}
	
	public Message produce(Message msg, int timeout) throws IOException, InterruptedException{ 
		msg.setCommand(Protocol.PRODUCE);
		return invokeSync(msg, timeout);  
	} 
	
	public Message produce(Message msg) throws IOException, InterruptedException{ 
		return produce(msg, invokeTimeout);  
	} 
	
	public void produceAsync(Message msg, ResultCallback callback) throws IOException {
		msg.setCommand(Protocol.PRODUCE);
		invokeAsync(msg, callback);
	}
	
	public Message consume(String topic) throws IOException, InterruptedException{
		return consume(topic, null, null);
	}
	
	public Message consume(String topic, String group) throws IOException, InterruptedException {
		return consume(topic, group, null);
	}
	 
	public Message consume(String topic, String group, Integer window) throws IOException, InterruptedException {
		Message msg = new Message();
		msg.setCommand(Protocol.CONSUME);
		msg.setTopic(topic);
		msg.setConsumeGroup(group);  
		msg.setConsumeWindow(window); 
		
		Message res = invokeSync(msg, invokeTimeout);
		if (res == null) return res;
		
		res.setId(res.getOriginId());
		res.removeHeader(Protocol.ORIGIN_ID); 
		return res;
	}  
	
	public void unconsume(String topic) throws IOException, InterruptedException {
		unconsume(topic, null);
	}
	
	public void unconsume(String topic, String group) throws IOException, InterruptedException {
		Message msg = new Message();
		msg.setCommand(Protocol.UNCONSUME);
		msg.setTopic(topic);
		msg.setConsumeGroup(group);   
		invokeAsync(msg, null); 
	}
	
	public TrackerInfo queryTracker() throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.TRACKER); 
		  
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, TrackerInfo.class); 
	}
	
	public ServerInfo queryServer() throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.SERVER); 
		  
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, ServerInfo.class); 
	}
	
	
	public String querySslCertificate(String server) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.SSL); 
		msg.setHeader("server", server);
		  
		Message res = invokeSync(msg, invokeTimeout); 
		if(res.getStatus() != 200){
			return null;
		}
		return res.getBodyString();
	}
	
	 
	public TopicInfo queryTopic(String topic) throws IOException, InterruptedException {
		Message msg = new Message();
		msg.setCommand(Protocol.QUERY);
		msg.setTopic(topic); 
		 
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, TopicInfo.class); 
	} 
	
	public ConsumeGroupInfo queryGroup(String topic, String group) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.QUERY);
		msg.setTopic(topic); 
		msg.setConsumeGroup(group);
		  
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, ConsumeGroupInfo.class); 
	}
	
	
	public TopicInfo declareTopic(String topic) throws IOException, InterruptedException{
		return declareTopic(topic, null);
	}
	
	public TopicInfo declareTopic(String topic, Integer topicMask) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.DECLARE);
		msg.setTopic(topic); 
		msg.setTopicMask(topicMask);
		 
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, TopicInfo.class); 
	}
	
	public ConsumeGroupInfo declareGroup(String topic, ConsumeGroup group) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.DECLARE);
		msg.setTopic(topic);
		msg.setConsumeGroup(group.getGroupName());
		msg.setGroupStartCopy(group.getStartCopy());
		msg.setGroupFilter(group.getFilter());
		msg.setGroupStartMsgId(group.getStartMsgId());
		msg.setGroupStartOffset(group.getStartOffset()); 
		msg.setGroupStartTime(group.getStartTime());
		msg.setTopicMask(group.getMask());
		
		
		Message res = invokeSync(msg, invokeTimeout);
		return parseResult(res, ConsumeGroupInfo.class); 
	}
	
	
	public void removeTopic(String topic) throws IOException, InterruptedException{
		removeGroup(topic, null);
	}
	
	public void removeGroup(String topic, String group) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.REMOVE);
		msg.setTopic(topic); 
		msg.setConsumeGroup(group);
		 
		Message res = invokeSync(msg, invokeTimeout);
		checkResult(res);
	}   
	 
	
	public void emptyTopic(String topic) throws IOException, InterruptedException{
		emptyGroup(topic, null);
	}    
	
	public void emptyGroup(String topic, String group) throws IOException, InterruptedException{
		Message msg = new Message();
		msg.setCommand(Protocol.EMPTY);
		msg.setTopic(topic); 
		msg.setConsumeGroup(group);
		 
		Message res = invokeSync(msg, invokeTimeout);
		checkResult(res); 
	}
	
	public void route(Message msg) throws IOException{
		msg.setCommand(Protocol.ROUTE);  
		msg.setAck(false); 
		//invoke message should be request typed, if not add origin_status header and change it to request type
		Integer status = msg.getStatus();
		if(status != null){
			msg.setOriginStatus(status); 
			msg.setStatus(null); //make it as request 
		} 
		
		invokeAsync(msg, null);  
	}  
	
	public Message invokeSync(Message msg, int timeout) throws IOException, InterruptedException {
		fillCommonHeaders(msg);
		return super.invokeSync(msg, timeout);
	}
	
	public Message invokeSync(Message msg) throws IOException, InterruptedException {
		return invokeSync(msg, invokeTimeout);
	}
	
	public void invokeAsync(Message msg, ResultCallback callback) throws IOException {
		fillCommonHeaders(msg);
	    super.invokeAsync(msg, callback);
	}
	
	
	
	
	private void fillCommonHeaders(Message msg){  
		if(msg.getToken() == null){
			msg.setToken(this.token);
		}
		msg.setVersion(Protocol.VERSION_VALUE); //Set Version
	}
	
	private void checkResult(Message msg){
		if(msg.getStatus() != 200 ){
			throw new MqException(msg.getBodyString());
		}
	}
	
	private  T parseResult(Message msg, Class clazz){
		checkResult(msg); 
		
		try{
			return JsonKit.parseObject(msg.getBodyString(), clazz);
		} catch (Exception e) {
			throw new MqException(msg.getBodyString(), e);
		}
	} 

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	} 
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy