Skip to content

Commit

Permalink
updating OttSessionProvider - removing session refresh scheduler + ad…
Browse files Browse the repository at this point in the history
…ding session refresh listener ++
  • Loading branch information
tehilar committed Mar 19, 2017
1 parent 8abcf89 commit c2208d7
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

public class PrimitiveResult extends BaseResult {
private String result;
private String result = null;

public PrimitiveResult(String result) {
super();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.kaltura.playkit.backend.phoenix;

import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Base64;
Expand All @@ -27,8 +26,8 @@
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

Expand All @@ -38,23 +37,25 @@

public class OttSessionProvider extends BaseSessionProvider {

public static final long TimeDelta = 2 * 60 * 60;//hour in seconds
private static final String TAG = "BaseResult";

public static final long TimeDelta = 2 * 60 * 60;//hour in seconds
public static final int DeltaPercent = 12;
public static final long IMMEDIATE_REFRESH = 1;
public static final long NEED_REFRESH = 0;
public static final String DummyUserId = "1";

private OttSessionParams sessionParams;
//private OttSessionParams sessionParams;
private String sessionUdid;
private String refreshToken;
private long refreshDelta = 9 * 60 * 60 * 24;//TimeDelta;
private int partnerId = 0;

private ScheduledFuture<?> scheduledRefreshTask;
private ScheduledThreadPoolExecutor refreshScheduleExecutor;
private Future<?> refreshTaskFurure;
private ThreadPoolExecutor refreshExecutor;
private AtomicBoolean refreshInProgress = new AtomicBoolean(false);

private OnCompletion<PrimitiveResult> sessionRecoveryCallback;

private OnCompletion<String> sessionRefreshListener;

//region refresh callable
private Callable<Boolean> refreshCallable = new Callable<Boolean>() {
Expand All @@ -74,8 +75,8 @@ public Boolean call() throws Exception {
PKLog.d(TAG, "start running refresh token");


if(scheduledRefreshTask != null && scheduledRefreshTask.isCancelled()){
scheduledRefreshTask = null;
if(refreshTaskFurure != null && refreshTaskFurure.isCancelled()){
refreshTaskFurure = null;
PKLog.d(TAG, "refresh operation got canceled");
return false;
}
Expand All @@ -97,14 +98,18 @@ public OttSessionProvider(String baseUrl, int partnerId) {
}

private void initRefreshExecutor() {
refreshScheduleExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2);
refreshExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
refreshExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
}

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
refreshScheduleExecutor.setRemoveOnCancelPolicy(true);
}
refreshScheduleExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
refreshScheduleExecutor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
refreshScheduleExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
/**
* sets a listener to listen to auto session refreshes
* @param listener
* @return
*/
public OttSessionProvider setRefreshListener(OnCompletion<String> listener){
this.sessionRefreshListener = listener;
return this;
}

/**
Expand All @@ -113,7 +118,8 @@ private void initRefreshExecutor() {
* @param udid
*/
public void startAnonymousSession(@Nullable String udid, final OnCompletion<PrimitiveResult> completion) {
this.sessionParams = new OttSessionParams().setUdid(udid);
//this.sessionParams = new OttSessionParams().setUdid(udid);
this.sessionUdid = udid;

MultiRequestBuilder multiRequest = PhoenixService.getMultirequest(apiBaseUrl, null);
multiRequest.add(OttUserService.anonymousLogin(apiBaseUrl, partnerId, udid),
Expand All @@ -139,10 +145,11 @@ public void onComplete(ResponseElement response) {
public void startSession(@NonNull String username, @NonNull String password, @Nullable String udid, final OnCompletion<PrimitiveResult> completion) {
// login user
//get session data for expiration time
this.sessionParams = new OttSessionParams().setPassword(password).setUsername(username).setUdid(udid);
//this.sessionParams = new OttSessionParams().setPassword(password).setUsername(username).setUdid(udid);
this.sessionUdid = udid;

MultiRequestBuilder multiRequest = PhoenixService.getMultirequest(apiBaseUrl, null);
multiRequest.add(OttUserService.userLogin(apiBaseUrl, partnerId, sessionParams.username, sessionParams.password, udid),
multiRequest.add(OttUserService.userLogin(apiBaseUrl, partnerId, username, password, udid),
PhoenixSessionService.get(apiBaseUrl, "{1:result:loginSession:ks}")).
completion(new OnRequestCompletion() {
@Override
Expand Down Expand Up @@ -209,7 +216,9 @@ private void handleStartSession(ResponseElement response, OnCompletion<Primitive
* @param udid
*/
public void maintainSession(@NonNull String ks, String refreshToken, String userId, String udid, OnCompletion<PrimitiveResult> sessionRecoveryCallback){
this.sessionParams = new OttSessionParams().setUdid(udid);
//this.sessionParams = new OttSessionParams().setUdid(udid);
this.sessionUdid = udid;

this.refreshToken = refreshToken;
this.sessionRecoveryCallback = sessionRecoveryCallback;
setSession(ks, Unset, userId);
Expand All @@ -219,13 +228,13 @@ public void maintainSession(@NonNull String ks, String refreshToken, String user
/**
* try to re-login with current credentials, if available
*/
private void renewSession(OnCompletion<PrimitiveResult> completion) {
/*private void renewSession(OnCompletion<PrimitiveResult> completion) {
if (sessionParams != null) {
if (sessionParams.username != null) {
startSession(sessionParams.username, sessionParams.password, sessionParams.udid, completion);
return;
} else if(isAnonymousSession() /*sessionParams.isAnonymous*/) {
} else if(isAnonymousSession() *//*sessionParams.isAnonymous*//*) {
startAnonymousSession(sessionParams.udid, completion);
return;
} // ?? in case session with no user credential expires, should we login as anonymous or return empty ks?
Expand All @@ -235,8 +244,7 @@ private void renewSession(OnCompletion<PrimitiveResult> completion) {
Log.e(TAG, "parameters needed for background session renewal are not available.");
//completion.onComplete(new PrimitiveResult().error(ErrorElement.SessionError.message("Session expired")));
completion.onComplete(new PrimitiveResult((String)null));//returns empty ks

}
}*/

public boolean isAnonymousSession() {
return getUserSessionType().equals(UserSessionType.Anonymous);
Expand All @@ -260,7 +268,7 @@ public void endSession(final OnCompletion<BaseResult> completion) {
return;
}

APIOkRequestsExecutor.getSingleton().queue(OttUserService.logout(apiBaseUrl, getSessionToken(), sessionParams.udid)
APIOkRequestsExecutor.getSingleton().queue(OttUserService.logout(apiBaseUrl, getSessionToken(), sessionUdid)
.completion(new OnRequestCompletion() {
@Override
public void onComplete(ResponseElement response) {
Expand All @@ -272,15 +280,15 @@ public void onComplete(ResponseElement response) {
PKLog.e(TAG, "endSession: session logout failed. clearing session data. " + error.getMessage());
}
OttSessionProvider.super.endSession();
sessionParams = null;
sessionUdid = null;
if (completion != null) {
completion.onComplete(new BaseResult(error));
}
}
}).build());

} else {
sessionParams = null;
sessionUdid = null;
}
}

Expand All @@ -297,31 +305,31 @@ public void getSessionToken(final OnCompletion<PrimitiveResult> completion) {
completion.onComplete(new PrimitiveResult(ks));
}
} else {
renewSession(completion);
// to get the refreshed ks on the completion callback
sessionRecoveryCallback = completion;
submitRefreshSessionTask();
}
}

protected String validateSession() {
long currentDate = System.currentTimeMillis() / 1000;
long timeLeft = expiryDate == Unset ? IMMEDIATE_REFRESH : expiryDate - currentDate;
long timeLeft = expiryDate == Unset ? NEED_REFRESH : expiryDate - currentDate;

String token = null;
if (timeLeft > 0) { // validate refreshToken expiration time
// returns current session token if current time didn't exceed the ks expiry time minus delta
// otherwise return null to submit refresh
if (refreshDelta > 0 && timeLeft > refreshDelta) {
token = getSessionToken();

if (timeLeft < refreshDelta) {
// call refreshToken
scheduleRefreshSessionTask(IMMEDIATE_REFRESH);
}
}

return token;
}


private void refreshSessionCall() {
// multi request needed to fetch the new expiration date.
MultiRequestBuilder multiRequest = PhoenixService.getMultirequest(apiBaseUrl, null);
multiRequest.add(OttUserService.refreshSession(apiBaseUrl, getSessionToken(), refreshToken, sessionParams.udid),
multiRequest.add(OttUserService.refreshSession(apiBaseUrl, getSessionToken(), refreshToken, sessionUdid),
PhoenixSessionService.get(apiBaseUrl, "{1:result:ks}"))
.completion(new OnRequestCompletion() {
@Override
Expand Down Expand Up @@ -349,35 +357,40 @@ public void onComplete(ResponseElement response) {
refreshResult = new PrimitiveResult(getSessionToken());
}
}
if(sessionRecoveryCallback != null){
sessionRecoveryCallback.onComplete(refreshResult != null ?

final PrimitiveResult refreshedKsResult = refreshResult != null ?
refreshResult :
new PrimitiveResult(ErrorElement.SessionError.addMessage(" FAILED TO RECOVER SESSION!!")));
new PrimitiveResult(ErrorElement.SessionError.addMessage(" FAILED TO RECOVER SESSION!!"));

if(sessionRecoveryCallback != null){
sessionRecoveryCallback.onComplete(refreshedKsResult);
sessionRecoveryCallback = null;
}

if(sessionRefreshListener != null && refreshResult != null){
sessionRefreshListener.onComplete(refreshResult.getResult());
}
}
});
APIOkRequestsExecutor.getSingleton().queue(multiRequest.build());
}


/**
* set scheduler to refresh tokens according to calculated delay. (expiration time and safety padding)
* @param delay - the time to schedule the refresh to. if the delay is 0, force refresh.
* submit task to refresh current session
*/
private synchronized void scheduleRefreshSessionTask(long delay) {
PKLog.i(TAG, "scheduling refresh in about " + delay + " sec from now");
scheduledRefreshTask = refreshScheduleExecutor.schedule(refreshCallable, delay, TimeUnit.SECONDS);
private synchronized void submitRefreshSessionTask() {
PKLog.i(TAG, "submit refresh session task");
refreshTaskFurure = refreshExecutor.submit(refreshCallable);
}

private void clearScheduled() {
Log.d(TAG, "clearScheduled: Thread - "+Thread.currentThread().getId());
private void cancelCurrentRefreshTask() {
Log.d(TAG, "cancelCurrentRefreshTask: Thread - "+Thread.currentThread().getId());

if(scheduledRefreshTask != null && !scheduledRefreshTask.isDone()){
scheduledRefreshTask.cancel(true);
if(refreshTaskFurure != null && !refreshTaskFurure.isDone()){
refreshTaskFurure.cancel(true);
}
scheduledRefreshTask = null;
refreshTaskFurure = null;
}

@Override
Expand All @@ -386,22 +399,23 @@ public void clearSession() {
refreshToken = null;
refreshDelta = TimeDelta;

clearScheduled();
cancelCurrentRefreshTask();
}

private boolean isScheduled() {
return scheduledRefreshTask != null && !scheduledRefreshTask.isDone() && !scheduledRefreshTask.isCancelled();
private boolean hasActiveRefreshTask() {
return refreshTaskFurure != null && !refreshTaskFurure.isDone() && !refreshTaskFurure.isCancelled();
}

@Override
protected void setSession(String sessionToken, long expiry, String userId) {
super.setSession(sessionToken, expiry, userId);
long delay = 1;
//long delay = 1;
if(expiry != Unset) {
updateRefreshDelta(expiry);
delay = expiry - refreshDelta;
//delay = expiry - refreshDelta;
} else {
submitRefreshSessionTask();
}
scheduleRefreshSessionTask(delay);
}

private void updateRefreshDelta(long expiry) {
Expand All @@ -415,7 +429,7 @@ private void updateRefreshDelta(long expiry) {
*/
public String encryptSession(){
StringBuilder data = new StringBuilder(getSessionToken()).append(" ~~ ")
.append(refreshToken).append(" ~~ ").append(sessionParams.udid());
.append(refreshToken).append(" ~~ ").append(sessionUdid);

return Base64.encodeToString(data.toString().getBytes(), Base64.NO_WRAP);
}
Expand All @@ -436,7 +450,7 @@ public boolean recoverSession(String encryptSession, OnCompletion<PrimitiveResul



private class OttSessionParams {
/*private class OttSessionParams {
private String udid = "";
private String username;
private String password;
Expand Down Expand Up @@ -469,10 +483,10 @@ public OttSessionParams setPassword(String password) {
return this;
}
/*public OttSessionParams setAnonymous() {
*//*public OttSessionParams setAnonymous() {
this.isAnonymous = true;
return this;
}*/
}
}*//*
}*/

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kaltura.playkit.backend.phoenix.data;

import com.kaltura.playkit.backend.BaseResult;
import com.kaltura.playkit.connect.ErrorElement;

/**
* @hide
Expand All @@ -11,6 +12,13 @@ public class KalturaLoginResponse extends BaseResult {
private KalturaLoginSession loginSession;
private KalturaOTTUser user;

public KalturaLoginResponse(ErrorElement error) {
super(error);
}

public KalturaLoginResponse() {
super();
}

public KalturaLoginSession getLoginSession() {
return loginSession;
Expand Down
Loading

0 comments on commit c2208d7

Please sign in to comment.