Subversion Repositories SmartDukaan

Rev

Rev 5466 | Rev 12616 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.serving.interceptors;

import in.shop2020.datalogger.EventType;
import in.shop2020.model.v1.user.Affiliate;
import in.shop2020.serving.services.UserSessionInfo;
import in.shop2020.serving.utils.DesEncrypter;
import in.shop2020.thrift.clients.UserClient;
import in.shop2020.utils.DataLogger;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class TrackingInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;
    private static Logger log = Logger.getLogger(TrackingInterceptor.class);

    private static final int SECONDS_IN_YEAR = 60 * 60 * 24 * 365;
    private static final int SECONDS_IN_DAY = 60 * 60 * 24;
    public static final String AFF_COOKIE = "uafc";
    public static final String SRC_COOKIE = "usrcc";
    public static final String SESSION_SRC_COOKIE = "sess_srcc";
    public static final String SRC_TIME_COOKIE = "usrctc";
    public static final String SESSION_SRC_TIME_COOKIE = "sess_srctc";
    public static final String SESSION_ID_COOKIE = "sess_idc";
    public static final String ENCRIPTION_STRING = "Saholic";
    private static final Set<String> paidAffIds;
    
    private String cookieDomain = "";
    private Cookie affCookie = null;
    private Cookie firstSourceCookie = null;
    private Cookie sessionSourceCookie = null;
    private Cookie firstSourceTimeCookie = null;
    private Cookie sessionSourceTimeCookie = null;
    private Cookie sessionIdCookie = null;
    private Map<String, Cookie> cookiesMap = null;
    
    private HttpServletRequest request;
    private HttpServletResponse response;
    private String referer;
    private String affId = null;
    private String utmSrc = null;
    
    static {
        paidAffIds = new HashSet<String>();
        paidAffIds.add("6");
        paidAffIds.add("38");
        paidAffIds.add("41");
        paidAffIds.add("43");
        paidAffIds.add("45");
    }

    public void setCookieDomain(String cookieDomain) {
        this.cookieDomain = cookieDomain;
    }

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        request = ServletActionContext.getRequest();
        response = ServletActionContext.getResponse();
        referer = request.getHeader("referer");
        affId = request.getParameter("afid");
        utmSrc = request.getParameter("utm_source");
        
        createCookiesMap();
        updateFirstSourceCookie();
        updateSessionSourceCookie();

        updateAffCookie();
        return invocation.invoke();
    }

    /**
     * Update first source cookie
     * 
     */
    private void updateFirstSourceCookie() {
        firstSourceCookie = (Cookie) cookiesMap.get(SRC_COOKIE);
        if (firstSourceCookie != null) {
            return;
        }
        String src = getSource();
        DesEncrypter des = new DesEncrypter(ENCRIPTION_STRING);
        String sourceCookieVal = des.encrypt(src);

        firstSourceCookie = createCookie(SRC_COOKIE, cookieDomain, sourceCookieVal, SECONDS_IN_YEAR);
        firstSourceTimeCookie = createCookie(SRC_TIME_COOKIE, cookieDomain, Long.toString((new Date()).getTime()), SECONDS_IN_YEAR);
        
        cookiesMap.put(SRC_COOKIE, firstSourceCookie);
        cookiesMap.put(SRC_TIME_COOKIE, firstSourceTimeCookie);

        response.addCookie(firstSourceCookie);
        response.addCookie(firstSourceTimeCookie);
    }

    private Cookie createCookie(String name, String domain, String value, Integer age) {
        Cookie cookie = new Cookie(name, value);
        if (age != null) {
            cookie.setMaxAge(age);
        }
        cookie.setPath("/");
        if (!domain.isEmpty()) {
            cookie.setDomain(domain);
        }
        return cookie;
    }

    /**
     * Update first source cookie
     * 
     */
    private void updateSessionSourceCookie() {
        sessionSourceCookie = (Cookie) cookiesMap.get(SESSION_SRC_COOKIE);
        if (sessionSourceCookie != null) {
            if (referer == null || referer.isEmpty() || referer.startsWith("http://www.saholic.com") || referer.startsWith("http://local.shop2020.in")) {
                log.info("No change in session cookie");
                return;
            }
        }
        String src = getSource();
        
        DesEncrypter des = new DesEncrypter(ENCRIPTION_STRING);
        String sessionSourceCookieVal = des.encrypt(src);

        //session source
        sessionSourceCookie = createCookie(SESSION_SRC_COOKIE, cookieDomain, sessionSourceCookieVal, null);
        cookiesMap.put(SESSION_SRC_COOKIE, sessionSourceCookie);
        log.info("new session cookie : " + sessionSourceCookieVal);

        //session time
        sessionSourceTimeCookie = createCookie(SESSION_SRC_TIME_COOKIE, cookieDomain, Long.toString((new Date()).getTime()), null);
        cookiesMap.put(SESSION_SRC_TIME_COOKIE, sessionSourceTimeCookie);
        
        UserSessionInfo userInfo = (UserSessionInfo) request
            .getAttribute(UserInterceptor.USER_INFO_COOKIE_NAME);

        //session id for chaining user actions over one year 
        sessionIdCookie = (Cookie) cookiesMap.get(SESSION_ID_COOKIE);
        if (sessionIdCookie == null) {
            String sessionId = request.getSession().getId();
            sessionIdCookie = createCookie(SESSION_ID_COOKIE, cookieDomain, sessionId, SECONDS_IN_YEAR);
            cookiesMap.put(SESSION_ID_COOKIE, sessionIdCookie);
            
            response.addCookie(sessionIdCookie);
            String firstSrc = "";
            firstSourceCookie = (Cookie) cookiesMap.get(SRC_COOKIE);
            if (firstSourceCookie != null) {
                firstSrc = des.decrypt(firstSourceCookie.getValue());
            }
            DataLogger.logData(EventType.NEW_SESSION, cookiesMap.get(SESSION_ID_COOKIE).getValue(),
                    userInfo.getUserId(), userInfo.getEmail(), src, firstSrc);
        }
        
        response.addCookie(sessionSourceCookie);
        response.addCookie(sessionSourceTimeCookie);
    }

    private void createCookiesMap() {
        cookiesMap = new HashMap<String, Cookie>();
        Cookie[] cookies = request.getCookies();
        // This check is necessary for the first request when no cookies are
        // sent.
        if (cookies == null)
            return;
        for (Cookie cookie : cookies) {
            cookiesMap.put(cookie.getName(), cookie);
        }
    }

    private void updateAffCookie() {
        try {
            if(affId == null || affId.isEmpty()) {
                if (referer != null && !referer.isEmpty() && !referer.startsWith("http://www.saholic.com") && !referer.startsWith("http://www.shop2020.in")) {
                    Cookie affCookie = cookiesMap.get(AFF_COOKIE);
                    if(affCookie != null) {
                        affCookie.setDomain(cookieDomain);
                        affCookie.setPath("/");
                        affCookie.setValue("");
                        affCookie.setMaxAge(0);
                        response.addCookie(affCookie);
                    }
                }
                return;
            }
            UserClient userContextServiceClient = new UserClient();
            in.shop2020.model.v1.user.UserContextService.Client userClient = userContextServiceClient.getClient();
            long affiliateId = Long.parseLong(affId);
            Affiliate affiliate = userClient.getAffiliateById(affiliateId);
            if (affiliate != null) {
                affCookie = (Cookie) cookiesMap.get(AFF_COOKIE);
                if (affCookie != null) {
                    Long.parseLong(affCookie.getValue());
                    if (affiliateId == Long.parseLong(affCookie.getValue())) {
                        return;
                    }
                }
                // create new aff cookie if affCookie ==null or affiliateId() != affCookie.
                Cookie newAffCookie = new Cookie(AFF_COOKIE, String.valueOf(affiliateId));
                newAffCookie.setMaxAge(SECONDS_IN_DAY * 5);
                newAffCookie.setPath("/");
                if (!cookieDomain.isEmpty()) {
                    newAffCookie.setDomain(cookieDomain);
                }
                cookiesMap.put(AFF_COOKIE, newAffCookie);
                response.addCookie(newAffCookie);
            }
        } catch (Exception e) {
            log.error("Failed to update affcookie.", e);
        }
        }
    
    private String getSource() {    
        String src = "";
        
        /* 
         * we are using http://email/ so that it is parsed properly in 
         * DailyProductwithSourceAggregatorServlet.getSource()
         */
        if (utmSrc != null) {
            src = "NEWSLETTER : (http://email/)";
        }
        else if (referer == null || referer.isEmpty()) {
            String queryString = request.getQueryString();
            queryString = queryString == null? "" : "?" + queryString;
            src = "DIRECT : " + "(" + request.getRequestURL() + "/" + queryString + ")";
        } 
        else if (referer.startsWith("http://www.saholic.com") || referer.startsWith("http://www.shop2020.in")) {
            src = "DIRECT : " + "(" + referer + ")";
        } 
        else if(paidAffIds.contains(affId)) {
            src = "PAID : " + "(" + referer + ")";
        }
        else if (referer.contains("google.co")) {
            src = "ORGANIC : " + "(" + referer + ")";
        }
        else {
            src = referer;
        }
        return src;
    }
}