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

com.gateway.invoke.AbstractApiProxy Maven / Gradle / Ivy

package com.gateway.invoke;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.fastjson.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.app.common.utils.Consts;
import com.app.common.utils.PResult;
import com.app.common.utils.StringUtil;
import com.gateway.connector.proto.Cmd;
import com.gateway.connector.proto.Format;
import com.gateway.connector.proto.Proto;
import com.gateway.connector.tcp.TcpConnector;
import com.gateway.connector.tcp.server.HttpServerHandler.HttpCallBack;
import com.gateway.connector.utils.LicenseUtil;
import com.gateway.constant.Constants;
import com.gateway.invoke.filter.apikey.ApiKeyService;
import com.gateway.invoke.gw.GWApi;
import com.gateway.invoke.security.ISecurityCheck;
import com.gateway.invoke.security.SecurityResult;
import com.gateway.message.MessageWrapper;
import com.gateway.message.SystemMessage;
import com.gateway.utils.JsonUtils;
import com.gateway.utils.ProtoUtils;
import com.gateway.utils.ThreadNameFactory;

import io.netty.handler.codec.http.HttpRequest;

public abstract class AbstractApiProxy implements ApiProxy {
	protected final static Logger logger = LoggerFactory.getLogger(AbstractApiProxy.class);
	protected ExecutorService executorService = Executors.newCachedThreadPool(new ThreadNameFactory("invoke"));
	protected ApiKeyService apiKeyService;

	public ApiKeyService getApiKeyService() {
		return apiKeyService;
	}

	public void setApiKeyService(ApiKeyService apiKeyService) {
		this.apiKeyService = apiKeyService;
	}

	private List securityChecks = new ArrayList();

	public List getSecurityChecks() {
		return securityChecks;
	}

	public void setSecurityChecks(List securityChecks) {
		this.securityChecks = securityChecks;
	}

	private SecurityResult securityCheck(SystemMessage sMsg, Proto message, String serverName, String method,
			String content,Map hm) {
		SecurityResult pr = new SecurityResult();
		for (ISecurityCheck iRule : securityChecks) {
			pr = iRule.check(sMsg, message, serverName, method, content,hm);
			if (!pr.isSuccess()) {
				logger.warn("{}:{} {} {} {} {}", message.getSessionId(), serverName, method, content, pr.code, pr.msg);
				break;
			}
		}
		return pr;
	}

	public TcpConnector tcpConnector;

	public void setTcpConnector(TcpConnector tcpConnector) {
		this.tcpConnector = tcpConnector;
	}

	public class ExecutorImpl implements Runnable {
		private SystemMessage sMsg;
		private Proto message;
		private String serverName;
		private String method;
		private String content;

		public ExecutorImpl(SystemMessage sMsg, Proto message, String serverName, String method, String content) {
			this.sMsg = sMsg;
			this.message = message;
			this.serverName = serverName;
			this.method = method;
			this.content = content;
		}

		@Override
		public void run() {

			processAppRequestReply(sMsg, message, serverName, method, content);// 
		}
	}

	public void processSubscribeWithImage(SystemMessage sMsg, Proto message, String serverName, String method,
			String content) {
		executorService.execute(new ExecutorImpl(sMsg, message, serverName, method, content));// 
	}

	private TopicManager topicManager;

	public TopicManager getTopicManager() {
		return topicManager;
	}

	public void setTopicManager(TopicManager topicManager) {
		this.topicManager = topicManager;
	}

	public MessageWrapper invoke(SystemMessage sMsg, Proto message) {
		byte[] body = message.getBody();

		String content = body != null ? new String(body) : "";

		logger.debug(String.format("cmd:%s,format:%s,seq:%s,sessionid:%s,body:%s", message.getCmd(),
				message.getFormat(), message.getSeq(), message.getSessionId(), content));

		if (message.getCmd() == Cmd.CONNECT) {

			return login(sMsg, message, content);

		} else if (message.getCmd() == Cmd.HEARTBEAT) {
			return new MessageWrapper(MessageWrapper.MessageProtocol.HEART_BEAT, message.getSessionId(), message);

		} else if (message.getCmd() == Cmd.SEND && message.getFormat() == Format.REQUEST) {

			Map hm = JsonUtils.Deserialize(content, Map.class);
			String serverName = "";

			if (hm.containsKey("serverName"))
				serverName = hm.get("serverName") + "";
			else if (hm.containsKey("server_name"))
				serverName = hm.get("server_name") + "";

			String method = hm.get("method") + "";

			Object contentObj = hm.get("content");
			if (contentObj != null) {
				if (contentObj instanceof String)
					content = contentObj + "";
				else
					content = JsonUtils.Serializer(contentObj);
			}
			logger.debug(String.format("request->severName:%s,method:%s,content:%s", serverName, method, content));
			SecurityResult pr = securityCheck(sMsg, message, serverName, method, content,hm);
			if (!pr.isSuccess()) {
				return createReply(pr.code, pr.msg, message);
			}
			if ("subscribe".equals(method) || "unsubscribe".equals(method)) {// 
				if ((!"gateway".equals(serverName) || Constants.ServerStatusTopic.equals(content))
						&& "subscribe".equals(method)) {
					processSubscribeWithImage(sMsg, message, serverName, method, content);// 
				}
				return processGateWayRequestReply(sMsg, message, serverName, method, content);

			} else {
				try {
					return processAppRequestReply(sMsg, message, serverName, method, content);
				} catch (Exception e) {
					logger.error(e.getMessage());
					return createReply(Consts.NoKnowCode, e.getMessage() + "", message);
				}

			}
		}

		return null;
	}

	public MessageWrapper createReply(int code, String msg, Proto message) {
		HashMap ehm = new HashMap<>();
		ehm.put(Consts.Code, code);
		ehm.put(Consts.Msg, msg);
		byte[] resultValue = JsonUtils.SerializerBytes(ehm);
		message.setBody(resultValue);
		message.setFormat(Format.REPLY);
		return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);
	}

	public MessageWrapper processGateWayRequestReply(SystemMessage sMsg, Proto message, String serverName,
			String method, String topic) {
		String sessionid = message.getSessionId();
		message = ProtoUtils.generateReplySuccess(sessionid, message.getCmd(), message.getSeq());
		if ("subscribe".equals(method)) {
			topicManager.add(sessionid, topic);
		} else if ("unsubscribe".equals(method)) {
			topicManager.remove(sessionid, topic);
		}
		return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);
	}

	public MessageWrapper login(SystemMessage sMsg, Proto message, String content) {
		MessageWrapper mw = null;
		Map hm = JsonUtils.Deserialize(content, Map.class);
		SecurityResult pr = securityCheck(sMsg, message, "LoginSvr", "login", content,hm);
		if (!pr.isSuccess()) {
			HashMap ehm = new HashMap<>();
			ehm.put(Consts.Code, pr.code);
			ehm.put(Consts.Msg, pr.msg);
			byte[] resultValue = JsonUtils.SerializerBytes(ehm);
			message.setBody(resultValue);
			message.setSessionId("");
			mw = new MessageWrapper(MessageWrapper.MessageProtocol.NO_CONNECT, message.getSessionId(), message);
			return mw;

		}
		 
		String userName = hm.get("userName") + "";
		String clientType = "api";

		Map extendParam = (Map) hm.get("extendParam");	 
		if (extendParam != null) {
			String tempClientType = (extendParam.containsKey("clientType") ? extendParam.get("clientType") + "" : "").toLowerCase();
			if(StringUtil.isBlank(tempClientType)) {
				if(extendParam.containsKey("param1")) {
					clientType="client";
				}
			}
		}
		int count = 1;
		int maxCount = 1;
		if (clientType.contains("api")&&sMsg.isLogin()) {
			count = LicenseUtil.getApiMaxSessionCount();
			maxCount = tcpConnector.getTcpSessionManager().getApiSessionCount();

		} else {
			count = LicenseUtil.getClientMaxSessionCount();
			int apiCount = tcpConnector.getTcpSessionManager().getApiSessionCount();
			maxCount = tcpConnector.getTcpSessionManager().getSessionCount() - apiCount;

		}
		if (maxCount >= count) {
			HashMap ehm = new HashMap<>();
			ehm.put("Code", "1050");
			ehm.put("Msg", "exceeding the maximum connection limit");
			byte[] resultValue = JsonUtils.SerializerBytes(ehm);
			message.setBody(resultValue);
			message.setSessionId("");
			mw = new MessageWrapper(MessageWrapper.MessageProtocol.NO_CONNECT, message.getSessionId(), message);
			return mw;
		}

		if (!sMsg.isLogin()) {
			mw = defaultLogin(sMsg, message, content);
		} else {
			mw = processLogin(sMsg, message, content);
		}
		mw.setUserName(userName);
		mw.setClientType(clientType);

		return mw;
	}

	public MessageWrapper defaultLogin(SystemMessage sMsg, Proto message, String content) {
		String sessionId = message.getSessionId();
		String userName = "";
		if (StringUtils.isEmpty(sessionId)) {
			sessionId = UUID.randomUUID().toString();
			message.setSessionId(sessionId);
			message.setBody(content.getBytes());
			try {
				HashMap hm = JsonUtils.Deserialize(content, HashMap.class);
				userName = hm.get("userName") + "";
			} catch (Exception e) {
			}
		}

		MessageWrapper mr = new MessageWrapper(MessageWrapper.MessageProtocol.CONNECT, sessionId, message);
		mr.setUserName(userName);
		return mr;
	}

	public MessageWrapper processLogin(SystemMessage sMsg, Proto message, String content) {
		return defaultLogin(sMsg, message, content);
	}

	public abstract MessageWrapper processAppRequestReply(SystemMessage sMsg, Proto message, String serverName,
			String method, String content);

	public abstract MessageWrapper invokeAsync(SystemMessage sMsg, Proto message, String serverName, String method,
			String content, com.gateway.connector.tcp.client.IMessage callback);

	private final static String api = "/api";

	public MessageWrapper invokeAsync(SystemMessage sMsg, Proto message,
			com.gateway.connector.tcp.client.IMessage callback) {
		try {
			byte[] body = message.getBody();

			String content = body != null ? new String(body) : "";
			if (message.getCmd() == Cmd.SEND && message.getFormat() == Format.REQUEST) {

				HttpCallBack httpCallBack = (HttpCallBack) callback;
				HttpRequest request = httpCallBack.getRequest();
				String url = request.uri().toString();
				String user_id = null;
				if (url.equals(api)) {
					String apiKey = request.headers().get("apikey");
					String expireStr = request.headers().get("expiry");
					String signature = request.headers().get("signature");
					long expire = Long.parseLong(expireStr);
					PResult pr = apiKeyService.verifySignature(apiKey, expire, content, signature);
					if (!pr.isSuccess()) {
						return createReply(pr.code, pr.msg, message);
					}
					user_id = pr.info1;
					message.setSessionId("gateway");
				}
				Map hm = JsonUtils.Deserialize(content, Map.class);
				String serverName = "";

				if (hm.containsKey("serverName"))
					serverName = hm.get("serverName") + "";
				else if (hm.containsKey("server_name"))
					serverName = hm.get("server_name") + "";
				String method = hm.get("method") + "";

				Object contentObj = hm.get("content");
				if (contentObj != null) {
					if (contentObj instanceof String)
						content = contentObj + "";
					else if (contentObj instanceof JSONArray) {
						JSONArray jsonArray = (JSONArray) contentObj;
						content = JsonUtils.Serializer(jsonArray);
					} else {
						JSONObject jo = (JSONObject) contentObj;
						if (jo != null) {
							jo.put("ip", sMsg.getRemoteAddress());
							if (StringUtils.isNotBlank(user_id)) {
								jo.put("user_id", user_id);
								jo.put("UserID", user_id);
							}
						}
						content = JsonUtils.Serializer(contentObj);
					}
				}

				logger.debug(String.format("request->severName:%s,method:%s,content:%s", serverName, method, content));
				SecurityResult pr = securityCheck(sMsg, message, serverName, method, content,hm);
				if (!pr.isSuccess()) {
					return createReply(pr.code, pr.msg, message);
				}
				return invokeAsync(sMsg, message, serverName, method, content, callback);

			}
			return null;
		} catch (Exception e) {
			String ct = GWApi.faileMsg(Consts.NoKnowCode, e.getMessage());
			logger.info("response:{}->remoteaddress:{},content:{}", message.getSessionId(), sMsg.getRemoteAddress(),
					ct);

			message.setBody(ct.getBytes());
			message.setFormat(Format.REPLY);
			return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy