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

com.shapestone.session.SessionService Maven / Gradle / Ivy

The newest version!
package com.shapestone.session;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import rx.Observable;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.*;

import static java.lang.System.currentTimeMillis;
import static java.time.Instant.ofEpochMilli;
import static java.time.LocalDateTime.now;
import static java.time.LocalDateTime.ofInstant;
import static java.time.ZoneId.systemDefault;
import static java.time.ZoneOffset.UTC;
import static java.time.temporal.ChronoUnit.MILLIS;
import static java.util.UUID.randomUUID;
import static rx.Observable.error;
import static rx.Observable.just;

/**
 * Name: Michael Williams
 * Date: 9/11/16.
 */
public class SessionService {

  private SessionRepository sessionRepository;
  private SessionServiceData sessionServiceData;
  private SessionEvenClient sessionEvenClient;

  public SessionService(SessionRepository sessionRepository,
                        SessionEvenClient sessionEvenClient,
                        SessionServiceData sessionServiceData) {
    this.sessionRepository = sessionRepository;
    this.sessionEvenClient = sessionEvenClient;
    this.sessionServiceData = sessionServiceData;
  }

  public Observable addSession(Session session) {
    final SessionOverseer overseer = new SessionOverseer(session);
    return sessionRepository
      .addSession(overseer.createStoreNewSession())
      .flatMap(newSession -> {
        //noinspection CodeBlock2Expr
        return sessionEvenClient
          .addSessionEvents(overseer.createSessionEvents())
          .flatMap( sessionHistories -> {
            //noinspection CodeBlock2Expr
            return Observable.just(newSession);
          });
      });
  }

  public Observable getSessionById(String sessionId) {
    //noinspection unchecked
    return sessionRepository
      .readSessionById(sessionId)
      .flatMap(sessionDataList -> {
        final Optional first = sessionDataList.stream().findFirst();
        if (first.isPresent()) {
          return just(first.get());
        } else {
          return error(new RuntimeException("No session with the id (" + sessionId + ") exists."));
        }
      });
  }

  public Observable> getActiveSessionById(String sessionId) {
    //noinspection unchecked
    return sessionRepository
      .readSessionById(sessionId)
      .flatMap(sessionDataList -> {
        final List sessions = new ArrayList<>();
        final Optional sessionOptional = sessionDataList.stream().findFirst();
        if (sessionOptional.isPresent()) {
          final Session session = sessionOptional.get();
          final ArrayList sessionArrayList = new ArrayList<>();
          if (isSessionNotExpired(session)) {
            sessionArrayList.add(session);
            return just(sessionArrayList);
          } else {
            return just(sessionArrayList);
          }
        } else {
          return just(sessions);
        }
      });
  }

  public Observable updateSession(Session session) {
    final SessionOverseer overseer = new SessionOverseer(session);
    return sessionRepository
      .updateSession(overseer.createStoreUpdatedSession())
      .flatMap(newSession -> {
        //noinspection CodeBlock2Expr
        return sessionRepository.updateSession(newSession);
    });
  }

  public Observable getOrCreatePartySession(Session session) {
    final long sessionExpiryTimeCutOff = getSessionExpiryTimeCutOff();
    return sessionRepository
      .readPartyActiveSessions(session.getPartyId(), sessionExpiryTimeCutOff)
      .flatMap((List activeSessions) -> {

        final Session newSession = new Session(session);

        final List sessions = filterByDevice(session, activeSessions);

        final Optional firstSession = sessions.stream().sorted(getComparator()).findFirst();

        if (!firstSession.isPresent()) {
          newSession.setSessionId("");
          return addSession(new SessionOverseer(newSession).createStoreNewSession());
        } else {
          final Session readSession = firstSession.get();
          if (isSessionExpired(readSession)) {
            newSession.setSessionId("");
            return addSession(new SessionOverseer(newSession).createStoreNewSession());
          } else {
            // Update modified date
            return updateSessionModifiedDate(readSession);
          }
        }
      });
  }

  private Observable updateSessionModifiedDate(Session session) {
    final Session updateSession = new Session();
    updateSession.setSessionId(session.getSessionId());
    updateSession.setModifiedDate(currentTimeMillis());
    return updateSession(updateSession);
  }

  private List filterByDevice(Session session, List activeSessions) {
    // TODO: Implement device check.
//    final SessionDevice sessionDevice = SessionDevice.builder()
//        .userAgent(session.getUserAgent())
//        .ipAddress(session.getIpAddress())
//        .language(session.getLanguage())
//        .fingerPrint(session.getFingerPrint())
//        .build();

//    return activeSessions.stream()
//        .filter(session1 -> sessionDevice
//            .equals(SessionDevice.builder()
//                .userAgent(session1.getUserAgent())
//                .ipAddress(session1.getIpAddress())
//                .language(session1.getLanguage())
//                .fingerPrint(session1.getFingerPrint())
//                .build()))
//        .collect(Collectors.toList());
    return activeSessions;
  }

  private Comparator getComparator() {
    return (o1, o2) -> {
      final Long modifiedDate1 = o1.getModifiedDate();
      final Long modifiedDate2 = o2.getModifiedDate();
      return modifiedDate1.compareTo(modifiedDate2);
    };
  }

  private LocalDateTime toLocalDateTime(Long timeInMillis) {
    return ofInstant(ofEpochMilli(timeInMillis), systemDefault());
  }

  private long getSessionExpiryTimeCutOff() {
    //final long millisPerSecond = 1000;
    final long sessionDurationMillis = sessionServiceData.getSessionDurationMillis();
    System.out.println("sessionDurationMillis = " + sessionDurationMillis);
    final ZonedDateTime utc = ZonedDateTime.now(UTC);

    final ZonedDateTime minus = utc.minus(sessionDurationMillis, MILLIS);
    System.out.println("minus.toEpochSecond() = " + minus.toEpochSecond());
    //return minus.toEpochSecond() * millisPerSecond;
    return minus.toInstant().toEpochMilli();
  }

  private Session addDeviceToExistingSession(Session existingSession, Session newDeviceSession) {
    existingSession.setModifiedDate(new Date().getTime());
    // nothing to update right now except modified time
    return existingSession;
  }

  private Session createNewSession(Session session) {
    Session newSession = new Session(session);
    newSession.setSessionId(randomUUID().toString());
    newSession.setModifiedDate(new Date().getTime());
    newSession.setCreatedDate(new Date().getTime());
    return newSession;
  }

  public Observable isSessionActive(String sessionId) {
    return sessionRepository
      .readActiveSessions(sessionId, getSessionExpiryTimeCutOff())
      .flatMap(sessions -> {
        final Optional first = sessions.stream().findFirst();
        if (first.isPresent()) {
          final SessionOverseer overseer = new SessionOverseer(new Session(sessionId));

          final Session updatedSession = overseer.createStoreUpdatedSession();
          final Observable updateObservable = sessionRepository.updateSession(updatedSession);

          final Observable> listObservable = sessionEvenClient.addSessionEvents(overseer.createSessionEvents());

          return Observable.zip(updateObservable, listObservable, (s, sh) -> {
            //noinspection CodeBlock2Expr
            return s != null;
          });
        } else {
          return error(new RuntimeException("Session with Id " + sessionId + " does not exits."));
        }
      });
  }

  public boolean isSessionNotExpired(Session session) {
    return !isSessionExpired(session);
  }

  public boolean isSessionExpired(Session session) {
    // Get last modified date
    final Long modifiedDate = session.getModifiedDate();

    if (modifiedDate == null || modifiedDate <= 0) {
      return true;
    }
    
    final long currentExpiryTime = getSessionExpiryTimeCutOff();

    // the session minimum modified date is before the
    return toLocalDateTime(currentExpiryTime).isAfter(toLocalDateTime(modifiedDate));
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @EqualsAndHashCode
  private static class SessionDevice {
    private String userAgent;
    private String ipAddress;
    private String language;
    private String fingerPrint;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy