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

io.baltoro.remote.RootServlet Maven / Gradle / Ivy

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

import java.io.IOException;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.glassfish.jersey.servlet.ServletContainer;

import io.baltoro.domain.App;
import io.baltoro.domain.AppUserSession;
import io.baltoro.domain.BODefaults;
import io.baltoro.domain.BaltoroAppAPI;
import io.baltoro.domain.BaltoroInstanceRequest;
import io.baltoro.domain.ObjectTypeEnum;
import io.baltoro.exception.ServiceException;
import io.baltoro.service.InstanceService;
import io.baltoro.service.Service;
import io.baltoro.service.ServiceFactory;
import io.baltoro.to.RequestContext;
import io.baltoro.to.UserSessionContext;
import io.baltoro.to.WSTO;
import io.baltoro.util.StringUtil;
import io.baltoro.util.UUIDGenerator;



public class RootServlet extends ServletContainer
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	static Log log = LogFactory.getLog(RootServlet.class);
	static Timer instMonitor;
	
	

	@Override
	public void init(ServletConfig config) throws ServletException
	{
		log.info("/////////////////////////////");
		log.info("/////////[Starting Root Servlet]///////////");
		log.info("/////////////////////////////");
		
		if(instMonitor != null)
		{
			super.init(config);
			return;
		}
			
		synchronized ("RootServlet".intern())
		{
			if(instMonitor == null)
			{
				instMonitor = new Timer();
				instMonitor.schedule(new TimerTask()
				{
					
					@Override
					public void run()
					{
						log.info("############################### close dead inst ");
						InstanceService service = ServiceFactory.get(InstanceService.class);
						service.closeDeadInstances();
						
					}
				}, 15000, 15000);
			}
		}
		
		super.init(config);
	}
	
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException 
	{
			
	    String serverName = request.getServerName();
		String appName = serverName.substring(0,serverName.indexOf('.'));
		String path = request.getRequestURI().toLowerCase();
		
		if(StringUtil.isNullOrEmpty(appName))
		{
			System.out.println("appName is null");
			response.sendError(HttpServletResponse.SC_BAD_REQUEST);
		}
		
		request.getSession(true);
		  
		System.out.println("**********************************");
		System.out.println(request.getMethod()+" ["+appName+"] -- "+path);
		System.out.println("**********************************");
	
		
		if(appName.equals("admin") && path.equals("/areyouthere"))
		{
			response.getWriter().write(""+System.currentTimeMillis());
			return;
		}
		
		if(appName.equals("admin") && path.equals("/getremaininginsancethreadscount"))
		{
			InstanceServletHelper helper = new InstanceServletHelper(request, response);
			int allowedCount = helper.getAllowedThreadPerInstance();
			response.getWriter().write(""+allowedCount);
			return;
		}
		
		if(appName.equals("admin") && path.equals("/getinstanceuuid"))
		{
			InstanceServletHelper helper = new InstanceServletHelper(request, response);
			String uuid = helper.getInstanceUuid();
			response.getWriter().write(uuid);
			return;
		}
		
		
		if(appName.equals("admin") && path.equals("/favicon.ico"))
		{
			super.service(request, response);
			return;
		}
		
		/*
		if(StringUtil.isNullOrEmpty(path) || path.equals("/"))
		{
			response.sendRedirect("/index.html");
			return;
		}
		*/
		
		
		  

		Service service = ServiceFactory.getInstance();
		App app = (App) service.getByName(appName, ObjectTypeEnum.APPW);
		if(app == null)
		{
			response.addHeader("BALTORO-ERROR", appName+ " does not exsists  "+path);
			response.getOutputStream().write( (appName+ " does not exsists  "+path).getBytes());
			return;
		}
		
		SessionInstance sessionInstance = getSessionInstance(app.getBaseUuid(), path, request, response);
		if(sessionInstance == null)
		{
			response.addHeader("BALTORO-ERROR", "App Node is not up !! "+path);
			response.getOutputStream().write( ("App Node ["+appName+"] is not up !! "+path).getBytes());
			return;
		}
		
		
		AppUserSession appUserSession = getAppUserSession(sessionInstance, request, response);
		
		CachePathMap pathCache = CachePathMap.get();
		BaltoroAppAPI api = pathCache.getBaltoroAppPath(app.getBaseUuid(), path);
		
		if(api == null)
		{
			response.sendError(HttpServletResponse.SC_NOT_FOUND, "resource not found");
			return;
		}
		
		System.out.println("==== > "+api.getUuid()+" ,,, "+path);
		
		
		BaltoroInstanceRequest req = BaltoroInstanceRequest.get();
		req.setAPIUuid(api.getUuid());
		req.setAppUuid(sessionInstance.getAppUuid());
		req.setAddPath(path);
		req.setInstanceUuid(sessionInstance.getInstanceUuid());
		req.setSizeKB(-1);
		req.setBltSessionId(appUserSession.getUuid());

		
		long t0 = System.currentTimeMillis();
		req.setStartedOn(new Timestamp(t0));
		
		BaltoroReqProcessor.get().add(req);
		
		try
		{
			byte[] bytes = processAppRequest(sessionInstance, appUserSession, api, appName, path, request, response);
			if(bytes != null)
			{
				response.getOutputStream().write(bytes);
				int size = bytes.length/1000 == 0 ? 1 : bytes.length/1000;
				req.setSizeKB(size);
			}
			else
			{
				System.out.println(path+" source not modified !!! ");
			}
		
			
		} 
		catch (ServiceException e)
		{
			e.printStackTrace();
			req.setError(e.getMessage());
			
		}
		catch (Exception e)
		{
			e.printStackTrace();
			req.setError(e.getMessage());
		}
		
	
		req.setMillisTaken((int)(System.currentTimeMillis() - t0));
		BaltoroReqProcessor.get().update(req);
		
		
	}
	
	
		
	
	private AppUserSession getAppUserSession(SessionInstance instance, HttpServletRequest request, HttpServletResponse response)
	{
	
		
		String bltSessionId = null;
		Optional cookiesOpt = Optional.ofNullable(request.getCookies());
		
		Cookie[] cookies = cookiesOpt.orElse(new Cookie[0]);
	
		
		for (int i = 0; i < cookies.length; i++)
		{
			Cookie cookie = cookies[i];
			
			if(cookie.getName().equals("BLT_SESSION_ID"))
			{
				bltSessionId = cookie.getValue();
			}
			
			if(bltSessionId !=null)
			{
				break;
			}
		}
		
		
		if(bltSessionId == null)
		{
			bltSessionId = UUIDGenerator.uuid("SESS");
			//Cookie cookie = new Cookie("BLT_SESSION_ID", bltSessionId);
			//response.addCookie(cookie);
			
		}
		
		AppUserSession appUserSession = SessionCache.get().get(bltSessionId);
		if(appUserSession == null)
		{
			InstanceService service = ServiceFactory.get(InstanceService.class);
			appUserSession = service.getUserSessionByUuid(bltSessionId);
			if(appUserSession != null)
			{
				SessionCache.get().add(bltSessionId, appUserSession);
			}
			
		}
		
		
		boolean timeout = false;
		if(appUserSession != null)
		{
			long t0 = appUserSession.getLastActivityOn().getTime();
			long t1 = System.currentTimeMillis();
			long ldif = t1-t0;
			long rdif = appUserSession.getTimeoutMin()*60*1000;
			if(ldif > rdif)
			{
				timeout = true;
			}
		}
			
		
		if(appUserSession == null || appUserSession.getState().equals("DEAD") || timeout)
		{
			InstanceService service = ServiceFactory.get(InstanceService.class);
			bltSessionId = UUIDGenerator.uuid("SESS");
			Cookie cookie = new Cookie("BLT_SESSION_ID", bltSessionId);
			cookie.setPath("/");
			cookie.setHttpOnly(true);
			response.addCookie(cookie);
		
			
			synchronized (bltSessionId.intern())
			{
				appUserSession = SessionCache.get().get(bltSessionId);
				if(appUserSession == null)
				{
					appUserSession = new AppUserSession();
					appUserSession.setUuid(bltSessionId);
					appUserSession.setAppUuid(instance.getAppUuid());
					appUserSession.setInstanceUuid(instance.getInstanceUuid());
					appUserSession.setCreatedBy(BODefaults.BASE_USER);
					appUserSession.setState("LIVE");
					appUserSession.setCreatedOn(new Timestamp(System.currentTimeMillis()));
					appUserSession.setTimeoutMin(20);
					appUserSession.setLastActivityOn(new Timestamp(System.currentTimeMillis()));
					service.createUserSession(appUserSession);
					SessionCache.get().add(bltSessionId, appUserSession);
					return appUserSession;
				}
			}
		}
		
		
		appUserSession.setLastActivityOn(new Timestamp(System.currentTimeMillis()));
		
		request.getSession().setAttribute("blt-session-id", bltSessionId);
		return appUserSession;
	}
	
	
	private SessionInstance getSessionInstance(String appUuid, String path,	HttpServletRequest request, HttpServletResponse response) 
	throws ServletException, IOException
	{
				
		String instanceUuid = null;
		Optional cookiesOpt = Optional.ofNullable(request.getCookies());
		
		Cookie[] cookies = cookiesOpt.orElse(new Cookie[0]);
	
		for (int i = 0; i < cookies.length; i++)
		{
			Cookie cookie = cookies[i];
			if(cookie.getName().equals("BLT_INSTANCE_UUID"))
			{
				instanceUuid = cookie.getValue();
			}
					
			if(instanceUuid !=null)
			{
				break;
			}
		}
			
		
		SessionInstance sessionInstance = WSSessions.get().getSession(appUuid,instanceUuid);
		
		if(sessionInstance == null)
		{
			return null;
		}
		
		if(instanceUuid==null || !instanceUuid.equals(sessionInstance.getInstanceUuid()))
		{
	
			Cookie cookie = new Cookie("BLT_INSTANCE_UUID", sessionInstance.getInstanceUuid());
			cookie.setPath("/");
			cookie.setHttpOnly(true);
			response.addCookie(cookie);
		}
		
		return sessionInstance;
	}
	
	
	private byte[] processAppRequest(SessionInstance sessionInstance, AppUserSession appUserSession, 
			BaltoroAppAPI bPath, String appName, String path,
			HttpServletRequest request, HttpServletResponse response) 
	throws ServletException, IOException, ServiceException
	{
				
		
		WSTO to = new WSTO();
		String uuid = UUID.randomUUID().toString();
		to.uuid = uuid;
		to.appName = appName;
		to.appUuid = sessionInstance.getAppUuid();
		to.instanceUuid = sessionInstance.getInstanceUuid();
		
		RequestContext rc = new RequestContext();
		rc.setRequestParams(request.getParameterMap());
		long lastModifiedFromBrowser = request.getDateHeader("If-Modified-Since");
		if(lastModifiedFromBrowser != -1)
		{
			rc.setIfModifiedSince(lastModifiedFromBrowser);
		}
		
		Enumeration headerNames = request.getHeaderNames();
		Map headerMap = new HashMap(100);
		while (headerNames.hasMoreElements()) 
		{
			String headerName = headerNames.nextElement();
			String headerValue = request.getHeader(headerName);
			
			headerMap.put(headerName, headerValue);
		}
		
		rc.setHeaders(headerMap);
		rc.setSessionId(appUserSession.getUuid());
		rc.setIp(request.getRemoteAddr());
		rc.setUrl(request.getRequestURL().toString());
		rc.setApiPath(path);
		rc.setMethod(request.getMethod());
		rc.setAuthRequired(bPath.isAuthRequired());
		rc.setRoles(bPath.getRoles());
		
		to.requestContext = rc;
		
		
		try
		{
		 
			boolean sendUserSession = false;
			if(!appUserSession.getInstanceUuid().equals(sessionInstance.getInstanceUuid()))
			{
				sendUserSession = true;
			}
			
			long t0 = sessionInstance.getStartedOn();
			long t1 = appUserSession.getCreatedOn().getTime();
			
			if(t0 > t1)
			{
				sendUserSession = true;
				appUserSession.setCreatedOn(new Timestamp(System.currentTimeMillis()));
			}
			
			if(sendUserSession)
			{
				appUserSession.setInstanceUuid(sessionInstance.getInstanceUuid());
				UserSessionContext uctx = new UserSessionContext();
				
				InstanceService service = ServiceFactory.get(InstanceService.class);
				AppUserSession appUserSession2 = service.getUserSessionByUuid(appUserSession.getUuid());
				
				uctx.setSessionUuid(appUserSession2.getUuid());
				uctx.setPrincipalName(appUserSession2.getUserName());
				uctx.setAttJson(appUserSession2.getAttJson());
				
				to.userSessionContext = uctx;
				
			}
			
			WSSessions.get().send(to);
			
	
	
			synchronized (uuid.intern())
			{
				uuid.intern().wait(20000);
				
				WSTO resTO = ResponseMap.getInstance().get(uuid);
				if(resTO != null)
				{
					//System.out.println(" ----> found response "+resTO);
					
					if(resTO.responseContext.getRedirect() != null)
					{
						System.out.println(" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ----> REDIRECT  "+resTO.responseContext.getRedirect());
						response.sendRedirect(resTO.responseContext.getRedirect());
						return null;
					}
					
					if(resTO.responseContext.getError() != null)
					{
						//response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, resTO.responseContext.getError());
						response.addHeader("BALTORO-ERROR", resTO.responseContext.getError());
						throw new ServiceException(resTO.responseContext.getError());
						//System.out.println(" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ----> errro  "+resTO.responseContext.getError());
						//return  null;
					}
					
					boolean sendNotModified = resTO.responseContext.isSendNotModified();
					
					if(sendNotModified)
					{
						response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
						return null;
					}
					
					if(resTO.responseContext.getData() == null)
					{
						//response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "response is null for "+uuid);
						response.addHeader("BALTORO-ERROR", "response is null for "+uuid);
						throw new ServiceException("response is null for uuid "+uuid);
						
					}
					
					String mineType = resTO.responseContext.getMimeType();
					if(mineType != null)
					{
						response.setContentType(mineType);
					}
					else
					{
						response.setContentType("text/html");
					}
					
					Long lmo = resTO.responseContext.getLastModifiedOn();
					if(!Objects.isNull(lmo))
					{
						System.out.println(path+" LMO >>>>> 111 >>>>>>> "+lmo.longValue());
						response.addDateHeader("Last-Modified", lmo.longValue());
					}
					else
					{
						System.out.println(path+" LMO >>>>> 2222 >>>>>>> null ");
					}
					
					
					 
					return resTO.responseContext.getData();
					
				}
				else
				{
					System.out.println(" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ----> response not found  "+uuid);
					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"response not found for uuid "+uuid);
					throw new ServiceException("response not found for uuid "+uuid);
					
				}
			}
			
		} 
		catch(ServiceException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			
			new ServletException(e);
		}
		

		return path.getBytes();
	}
	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy