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