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

io.baltoro.client.RequestWorker Maven / Gradle / Ivy

There is a newer version: 4.0.12
Show newest version
package io.baltoro.client;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.websocket.OnClose;
import javax.websocket.OnOpen;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.baltoro.client.util.StringUtil;
import io.baltoro.exp.AuthException;
import io.baltoro.features.AbstractFilter;
import io.baltoro.features.Param;
import io.baltoro.to.APIError;
import io.baltoro.to.RequestContext;
import io.baltoro.to.ResponseContext;
import io.baltoro.to.UserSessionContext;
import io.baltoro.to.WSTO;
import io.baltoro.to.WebSocketContext;

public class RequestWorker extends Thread
{
	private WSTO to;
	UserSession userSession;
	List filters = new ArrayList<>();
	static ObjectMapper mapper = new ObjectMapper();
	boolean run = true;
	static int _count;
	int count;
	long lastWorked = System.currentTimeMillis();
	
	/*
	static ThreadLocal requestCtx = new ThreadLocal<>();
	static ThreadLocal responseCtx = new ThreadLocal<>();
	static ThreadLocal wsCtx = new ThreadLocal<>();
	*/
	
	static ThreadLocal userSessionIdCtx = new ThreadLocal<>();
	
	RequestWorker()
	{
		/*
		synchronized (RequestWorker.class.getName().intern())
		{
			count = _count++;
		}
		*/
	}
	
	void set(WSTO to)
	{
		//System.out.println(this+" ........... on set  : "+to.requestContext.getApiPath());
		this.to = to;
		synchronized (this)
		{
			this.notify();
		}
	}
	
	void clear()
	{
		this.to = null;
		this.userSession = null;
		filters.clear();
	}
	
	public void run()
	{
		while (run)
		{
			if(to == null)
			{
				synchronized (this)
				{
					try
					{
						this.wait(10000);
						
						if(to == null)
						{
							//System.out.println("REQUEST thread no work to do  "+this+",  --- "+count+",,,"+WorkerPool.info());
						
							continue;
						}
					} 
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				}
			}
			
			try
			{
				//String url = to.requestContext.getApiPath();
				//System.out.println(this+" 1........... on work  : "+url);
				work();
				//System.out.println(this+" 2........... on work  : "+url);
			} 
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally 
			{
				lastWorked = System.currentTimeMillis();
				to = null;
				WorkerPool.done(this);
			}
			
		}
	}
	
	private void work()
	{

		if(to == null)
		{
			System.out.println("ERROR PARSING WSTO !!!!!!! CHECK ");
			return;
		}
		
		/*
		if(to.webSocketContext != null && !to.webSocketContext.getApiPath().endsWith("onopen"))
		{
			
			
			WebSocketContext ws = to.webSocketContext;
			//wsCtx.set(ws);
			
			//System.out.println(" ws ctx  >>>>>>>>>>>>>>>>>>>>>> : "+ws.getApiPath());
			
			WebMethod wm = null;
			try
			{
				 wm = WebMethodMap.getInstance().getMethod(ws.getApiPath());
				if (wm == null)
				{
					//System.out.println("no method for : "+ws.getApiPath());
					throw new Exception("no method for : "+ws.getApiPath());
				}
				
				Object obj = executeMethod(wm, to);
			} 
			catch (Exception e)
			{
				e.printStackTrace();
			}
			
			return;
		}
		*/
		
		RequestContext req = to.requestContext;
		//requestCtx.set(req);
		
		ResponseContext res = new ResponseContext();
		res.setHeaders(new HashMap<>());
		to.responseContext = res;
		res.setSessionId(req.getSessionId());
		
		userSessionIdCtx.set(req.getSessionId());
		//responseCtx.set(res);
	
		
		
		try
		{
			
			process();
		
		} 
		catch (Exception e)
		{
			if (e instanceof SendRedirect)
			{
				SendRedirect sd = (SendRedirect) e;
				res.setRedirect(sd.getUrl());
			}
			else if (e.getCause() instanceof SendRedirect)
			{
				SendRedirect sd = (SendRedirect) e.getCause();
				res.setRedirect(sd.getUrl());
			} 
			else if (e instanceof APIError)
			{
				APIError er = (APIError) e;
				res.setError(er.getMessage());
			}
			else if (e.getCause() instanceof APIError)
			{
				APIError er = (APIError) e.getCause();
				res.setRedirect(er.getMessage());
			} 
			else if (e instanceof AuthException)
			{
				res.setError(e.getMessage());
			}
			else
			{
				e.printStackTrace();
				res.setError(e.getMessage()+"---"+(e.getCause() !=null ? e.getCause().getMessage() : ""));
				
			}

		}
		finally 
		{
			
			/*
			if(to.webSocketContext == null)
			{
				to.requestContext = null;
			}
			
			
			byte[] bytes = null;
			try
			{
				bytes = ObjectUtil.toJason(to);
			} 
			catch (Exception e)
			{
				e.printStackTrace();
				System.out.println("RESPONSE CANNOT CONVERT TO JSON , !!!! CHECK !");
				//return;
			}
			
			
			if(bytes != null)
			{
				System.out.println("** >>>>>>>>>>>>>>>> executing "+path+" return json len : "+bytes.length);
				ByteBuffer buffer = ByteBuffer.wrap(bytes);
				WSSessions.get().addToResponseQueue(buffer);
			}
			*/
			
			//System.out.println("** >>>>>>>>>>>>>>>> executing "+to.requestContext.getApiPath());
			WSSessions.get().addToResponseQueue(to);
			//WorkerPool.done(this);
			
			//requestCtx.set(null);
			//wsCtx.set(null);
			
		
		}

	}
	
	

	private void process() throws Exception
	{

		RequestContext req = to.requestContext;
		ResponseContext res = to.responseContext;
		
		if (StringUtil.isNotNullAndNotEmpty(req.getSessionId()))
		{
			String reqSessionId = req.getSessionId();
			userSession = SessionManager.getSession(reqSessionId);
			UserSessionContext uctx = to.userSessionContext;
			if(uctx != null)
			{
				String userName = uctx.getPrincipalName();
				userSession.userName = userName;
				
				Map attMap = new HashMap<>();
				try
				{
					if(uctx.getAttJson() != null)
					{
						attMap = mapper.readValue(uctx.getAttJson(), Map.class);
					}
					
				} 
				catch (IOException e)
				{
					e.printStackTrace();
				}
				
				for (String key : attMap.keySet())
				{
					String val = attMap.get(key);
					userSession.attMap.put(key, val);
				}
			}
			
			
		}
		
		
		
		List filterNames = WebMethodMap.getInstance().getFilterNames();
		for (String fNames : filterNames)
		{
			Class _class = WebMethodMap.getInstance().getFilterClass(fNames);
			try
			{
				//System.out.println(" filter  >>>>>>> "+fNames);
				AbstractFilter filter = _class.newInstance();
				filters.add(filter);
				filter.before(to, userSession);
			} 
			catch (Exception e)
			{
				if (e instanceof SendRedirect)
				{
					SendRedirect sd = (SendRedirect) e;
					res.setRedirect(sd.getUrl());
					return;
				} 
				else if (e.getCause() instanceof SendRedirect)
				{
					SendRedirect sd = (SendRedirect) e.getCause();
					res.setRedirect(sd.getUrl());
					return;
				} 
				else if (e instanceof AuthException)
				{
					res.setError(e.getMessage());
					return;
				} 
				else
				{
					e.printStackTrace();
				}

			}
		}
		
		

		WebMethod wm = WebMethodMap.getInstance().getMethod(req.getApiPath());
		if (wm == null)
		{
			String path = req.getApiPath();
			String[] tokens = path.split("/");
			for (int i = 0; i < tokens.length; i++)
			{
				int lIndex = path.lastIndexOf('/');
				if(lIndex == -1)
				{
					System.out.println("no index found / error path="+path);
				}
				path = path.substring(0, lIndex);
				String lPath = req.getApiPath().substring(lIndex + 1);
				wm = WebMethodMap.getInstance().getMethod(path + "/*");
				if (wm != null)
				{
					req.setRelativePath(lPath);
					break;
				}

			}
		}

		

		if (wm == null)
		{
			res.setError("API for path [" + req.getApiPath() + "] not found ");
		}

		try
		{

			checkAuth(wm, to, wm.getWebPath());
			Object returnObj = executeMethod(wm, to);
			
			for (AbstractFilter filter : filters)
			{
				filter.after(returnObj, to, userSession);
			}
			

			//System.out.println(")))) >>>>>>>>>>>>>>>> executing "+to.requestContext.getApiPath()+" return : "+returnObj);
		
			
			if (returnObj != null)
			{
				if(returnObj instanceof String)
				{
					to.responseContext.setData(((String) returnObj).getBytes());
				}
				else if (returnObj instanceof byte[])
				{
					to.responseContext.setData((byte[]) returnObj);
				} 
				else
				{
					to.responseContext.setData(mapper.writeValueAsBytes(returnObj));
				}
			}

		} 
		catch (Exception e)
		{
			throw e;
		}


	}

	private void checkAuth(WebMethod wm, WSTO to, String path) throws AuthException
	{
		if (!wm.authRequired)
		{
			return;
		}

		String sessionId = to.requestContext.getSessionId();
		if (sessionId == null)
		{
			throw new AuthException("sessionId is null, cannot execute " + path);
		}

		UserSession userSession = Baltoro.getUserSession();
		if (userSession == null)
		{
			throw new AuthException("session object is null, cannot execute " + path);
		}

		String userName = userSession.getUserName();
		if (userName == null)
		{
			throw new AuthException("no auth user in session, cannot execute " + path);
		}
	}

	private Object executeMethod(WebMethod wMethod, WSTO to) throws Exception
	{
		RequestContext reqCtx = to.requestContext;
		ResponseContext resCtx = to.responseContext;
		WebSocketContext wsCtx = to.webSocketContext;
		WSSession wssession = null;
		if(wsCtx != null)
		{
			wssession = (WSSession) WSAPIClassInstance.get().get(wsCtx.getInitRequestUuid(), WSSession.class);
			if(wssession == null)
			{
				wssession = new WSSession(to);
			}
		}
		
		
		Map requestParam = reqCtx == null ? null : reqCtx.getRequestParams();
		if (requestParam == null || requestParam.size() == 0)
		{
			requestParam = new HashMap();
		}

		Class _class = wMethod.get_class();
		Method method = wMethod.getMethod();

		//boolean noParam = true;
		Parameter[] methodParms = method.getParameters();
		Object[] methodInputData = new Object[methodParms.length];

		for (int i = 0; i < methodParms.length; i++)
		{
			//noParam = true;
			Parameter param = methodParms[i];
			Class paramClass = param.getType();

			String annoName = null;
			Annotation[] annos = param.getAnnotations();
			
			for (int j = 0; j < annos.length; j++)
			{
				Annotation anno = annos[j];
				if (anno.annotationType() == Param.class)
				{
					Param annoPraram = (Param) anno;
					annoName = annoPraram.value();
					break;
				}

			}

			String[] requestValue = requestParam.get(annoName);
			if(annoName != null && requestValue == null)
			{
				StringBuffer buffer = new StringBuffer();
				for (String paramName : requestParam.keySet())
				{
					buffer.append(paramName+",");
				}
				throw new Exception(annoName+" is not submitted as a parameter. incoming params ["+buffer.toString()+"] ");
			}

			
			if(annoName != null)
			{
				if (paramClass == String.class && requestValue != null)
				{
					methodInputData[i] = requestValue[0];
				} 
				else if (paramClass == String[].class && requestValue != null)
				{
					methodInputData[i] = requestValue;
				} 
			}
			else
			{
				if (paramClass == RequestContext.class)
				{
					methodInputData[i] = reqCtx;
				} 
				else if (paramClass == ResponseContext.class)
				{
					methodInputData[i] = resCtx;
				}
				else if (paramClass == WebSocketContext.class)
				{
					methodInputData[i] = wsCtx;
				}
				else if (paramClass == UserSession.class)
				{
					methodInputData[i] = userSession;
				}
				else if (paramClass == WSSession.class)
				{
					methodInputData[i] = wssession;
				}
			}
			
			if (paramClass == byte[].class && wsCtx != null && wsCtx.getApiPath().endsWith("onmessage"))
			{
				methodInputData[i] = wsCtx.getData();
			}
			
			if (paramClass == String.class && wsCtx != null && wsCtx.getApiPath().endsWith("onmessage"))
			{
				methodInputData[i] = wsCtx.getMessage();
			}

		}
		

		Object  classInstance = null;
		
		if(wMethod.isWebSocket())
		{
		
			if(method.isAnnotationPresent(OnOpen.class))
			{
				classInstance = _class.newInstance();
				WSAPIClassInstance.get().add(wsCtx.getInitRequestUuid(),_class, classInstance);
				WSAPIClassInstance.get().add(wsCtx.getInitRequestUuid(),WSSession.class, wssession);
				WSAPIClassInstance.get().add(wsCtx.getInitRequestUuid(),WSTO.class, to);
				
				System.out.println("classInstance cache OnOPen "+wsCtx.getInitRequestUuid()+" - "+_class+" - "+wsCtx.getWsSessionUuid());
			}
			
			classInstance = WSAPIClassInstance.get().get(wsCtx.getInitRequestUuid(), _class);
			
			
			
			
			if(method.isAnnotationPresent(OnClose.class))
			{
				WSAPIClassInstance.get().remove(wsCtx.getInitRequestUuid(), _class);
				WSAPIClassInstance.get().remove(wsCtx.getInitRequestUuid(),WSSession.class);
				WSAPIClassInstance.get().remove(wsCtx.getInitRequestUuid(),WSTO.class);
			}
		}
		else
		{
			classInstance = _class.newInstance();
		}
		
		if(classInstance == null)
		{
			System.out.println("classInstance is null why ? "+wsCtx.getInitRequestUuid()+" - "+_class);
			return null;
		}
	
			
		Object returnObj = method.invoke(classInstance, methodInputData);

	
			
		return returnObj;

	}
	
	/*
	@Override
	public boolean equals(Object obj)
	{
		return count == ((RequestWorker)obj).count;
	}
	*/
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy