com.akeyless.auth.CredsRenewal Maven / Gradle / Ivy
package com.akeyless.auth;
import com.akeyless.auth.swagger.model.SystemUserCredentialsReplyObj;
import java.util.Date;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.NoOpLog;
public class CredsRenewal implements Runnable {
public enum Mode {
LAZY,
EAGER;
}
private Log log = new NoOpLog();
private Mode mode = Mode.LAZY;
private ScheduledExecutorService scheduler;
private volatile ScheduledFuture> renewalTask;
protected ReadWriteLock lock = new ReentrantReadWriteLock();
private Authenticator authenticator;
private volatile String authCreds;
private volatile String uamCreds;
private volatile String kfmCreds;
private volatile long expiry = 0;
private int renewalLatency = 60 * 30; // The amount of time before expiry to start the credentials renewal in seconds.
private int credsThreshold = 60; // The amount of time before expiry to stop using the credentials in seconds.
public CredsRenewal(Authenticator authenticator) {
this.authenticator = authenticator;
initScheduler();
}
public CredsRenewal(Authenticator authenticator, Mode mode, Log log) {
this.authenticator = authenticator;
this.mode = mode;
if(log != null)
this.log = log;
initScheduler();
}
public String getAuthCreds() throws CredsRenewalException {
validate();
return authCreds;
}
public String getUamCreds() throws CredsRenewalException {
validate();
return uamCreds;
}
public String getKfmCreds() throws CredsRenewalException {
validate();
return kfmCreds;
}
private void initScheduler() {
if(isLazyMode()){
return;
}
renewCreds();
scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread t = Executors.defaultThreadFactory().newThread(runnable);
t.setDaemon(true);
return t;
}
});
long nextRenewal = Math.max(expiry - (currentTimeInSec()+renewalLatency),1);
scheduleRenewalTask(nextRenewal);
log.info("Credentials successfully renewed. Expires at: " + new Date(expiry*1000).toString());
}
@Override
public void run() {
try {
renewCreds();
long nextRenewal = Math.max(expiry - (currentTimeInSec()+renewalLatency),1);
scheduleRenewalTask(nextRenewal);
log.info("Credentials successfully renewed. Expires at: " + new Date(expiry*1000).toString());
} catch (Exception e) {
log.error("Credentials renewal failed. Err:"+e.getMessage());
scheduleRenewalTask(1);
}
}
private synchronized void renewCreds() throws CredsRenewalException {
if (isNotExpired()) {
return;
}
log.debug("Starts renewing credentials");
try {
SystemUserCredentialsReplyObj tempCreds = authenticator.authenticate();
authCreds = tempCreds.getAuthCreds();
uamCreds = tempCreds.getUamCreds();
kfmCreds = tempCreds.getKfmCreds();
expiry = tempCreds.getExpiry() == null ? 0L : tempCreds.getExpiry();
} catch (Exception e) {
throw new CredsRenewalException(e);
}
}
private void validate() throws CredsRenewalException {
if (isNotExpired()) {
return;
}
renewCreds();
if (isEagerMode() && renewalTask != null && renewalTask.isDone()) {
// For some reason, the task has been unexpectedly terminated, so restart it immediately
log.warn("Credentials renewal task has been unexpectedly terminated, restarts again");
scheduleRenewalTask(0);
}
}
private boolean isNotExpired() {
return (expiry - currentTimeInSec()) >= credsThreshold;
}
private boolean isLazyMode() {
return mode.equals(Mode.LAZY);
}
private boolean isEagerMode() {
return mode.equals(Mode.EAGER);
}
private long currentTimeInSec() {
return System.currentTimeMillis() / 1000L;
}
private synchronized void scheduleRenewalTask(long delay) {
renewalTask = scheduler.schedule(this, delay, TimeUnit.SECONDS);
}
}