Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot Reload for creds #101

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ibm.etcd</groupId>
<artifactId>etcd-java</artifactId>
<version>0.0.25-SNAPSHOT</version>
<version>0.0.25</version>
<packaging>jar</packaging>

<name>etcd-java</name>
Expand Down
30 changes: 25 additions & 5 deletions src/main/java/com/ibm/etcd/client/EtcdClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,13 @@
import io.netty.util.IllegalReferenceCountException;
import io.netty.util.ReferenceCounted;
import io.netty.util.concurrent.FastThreadLocalThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EtcdClient implements KvStoreClient {

private static final Logger logger = LoggerFactory.getLogger(EtcdClient.class);

private static final Key<String> TOKEN_KEY =
Key.of("token", Metadata.ASCII_STRING_MARSHALLER);

Expand All @@ -111,6 +115,7 @@ public class EtcdClient implements KvStoreClient {

public static final long DEFAULT_TIMEOUT_MS = 10_000L; // 10sec default
public static final int DEFAULT_SESSION_TIMEOUT_SECS = 20; // 20sec default
public static final long AUTH_RETRY_TIMEOUT_MS = 100L; // 100ms default

// (not intended to be strict hostname validation here)
protected static final Pattern ADDR_PATT =
Expand All @@ -120,7 +125,7 @@ public class EtcdClient implements KvStoreClient {

private final int sessionTimeoutSecs;

private final ByteString name, password;
private ByteString name, password;

private final MultithreadEventLoopGroup internalExecutor;
private final ScheduledExecutorService sharedInternalExecutor;
Expand Down Expand Up @@ -580,7 +585,7 @@ public boolean isClosed() {
// ------ authentication logic

private static final Set<Code> OTHER_AUTH_FAILURE_CODES = ImmutableSet.of(
Code.INVALID_ARGUMENT, Code.FAILED_PRECONDITION, Code.PERMISSION_DENIED, Code.UNKNOWN);
Code.INVALID_ARGUMENT, Code.FAILED_PRECONDITION, Code.PERMISSION_DENIED, Code.INTERNAL, Code.UNKNOWN);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a problem with incorrect auth case identification. Had to add Code.INTERNAL to OTHER_AUTH_FAILURE_CODES among existing.


// Various different errors can imply a re-auth is required (sometimes non-obvious),
// so we cover most related messages to be safe. This should not cause problems since
Expand Down Expand Up @@ -665,11 +670,10 @@ public void applyRequestMetadata(RequestInfo requestInfo,
failStatus = Status.UNAUTHENTICATED
.withDescription("(Re)authentication RPC failed")
.withCause(failure);
authFailRetryTime = System.currentTimeMillis() + 5_000L;
authFailRetryTime = System.currentTimeMillis() + AUTH_RETRY_TIMEOUT_MS;
} else {
failStatus = Status.fromThrowable(failure);
// If this was a real auth failure, postpone further attempts a bit longer
authFailRetryTime = System.currentTimeMillis() + 15_000L;
authFailRetryTime = System.currentTimeMillis() + AUTH_RETRY_TIMEOUT_MS;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for 15s every time I hot reload is bad. Most likely it is good to turn the delay off (or make it a parameter).

}
lastAuthFailStatus = failStatus;
// Augment with the RPC failure that triggered the re-authentication,
Expand Down Expand Up @@ -697,6 +701,8 @@ private static Metadata tokenHeader(AuthenticateResponse authResponse) {
}

private ListenableFuture<AuthenticateResponse> authenticate() {
logger.error("Auth token seems to be incorrect or uninitialized yet. Getting new token with current etcd creds...");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to show in console some things happen..


AuthenticateRequest request = AuthenticateRequest.newBuilder()
.setNameBytes(name).setPasswordBytes(password).build();
// no call creds for auth call
Expand Down Expand Up @@ -770,6 +776,20 @@ public PersistentLease getSessionLease() {
return sl;
}

@Override
public void updateCredentials(String name, String password) {
this.name = ByteString.copyFromUtf8(name);
this.password = ByteString.copyFromUtf8(password);
}

@Override
public List<String> getCredentials() {
return Arrays.asList(
this.name.toStringUtf8(),
this.password.toStringUtf8()
);
}

public Executor getExecutor() {
return grpc.getResponseExecutor();
}
Expand Down
19 changes: 3 additions & 16 deletions src/main/java/com/ibm/etcd/client/GrpcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,8 @@ private <ReqT,R> ListenableFuture<R> call(MethodDescriptor<ReqT,R> method,
// multiple retries disabled or deadline expired
return Futures.immediateFailedFuture(t);
}
boolean reauth = false;
if (authProvider.requiresReauth(t)) {
if (afterReauth) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not understand why to have such condition...

// if we have an auth failure immediately following a reauth, give up
// (important to avoid infinite loop of auth failures)
return Futures.immediateFailedFuture(t);
}
reauthenticate(baseCallOpts, t);
reauth = true;
} else if (!retry.retry(t, request)) {
boolean reauth = reauthIfRequired(t, baseCallOpts);;
if (!reauth && !retry.retry(t, request)) {
// retry predicate says no (non retryable request and/or error)
return Futures.immediateFailedFuture(t);
}
Expand Down Expand Up @@ -442,8 +434,6 @@ final class ResilientBiDiStream<ReqT,RespT> {
private boolean finished;
private Throwable error;

private boolean lastAuthFailed;

/**
*
* @param method
Expand Down Expand Up @@ -636,7 +626,6 @@ public void beforeStart(ClientCallStreamObserver<ReqT> rs) {
// called from grpc response thread
@Override
public void onNext(RespT value) {
lastAuthFailed = false;
respStream.onNext(value);
}
// called from grpc response thread
Expand All @@ -646,10 +635,9 @@ public void onError(Throwable t) {
if (finished) {
finalError = true;
} else {
reauthed = !lastAuthFailed && reauthIfRequired(t, sentCallOptions);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

reauthed = reauthIfRequired(t, sentCallOptions);
finalError = !reauthed && !retryableStreamError(t);
}
lastAuthFailed = reauthed;
if (!finalError) {
int errCount = -1;
String msg;
Expand Down Expand Up @@ -703,7 +691,6 @@ public void onError(Throwable t) {
// called from grpc response thread
@Override
public void onCompleted() {
lastAuthFailed = false;
if (!finished) {
logger.warn("Unexpected onCompleted received"
+ " for stream of method " + method.getFullMethodName());
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/ibm/etcd/client/KvStoreClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.ibm.etcd.client;

import java.io.Closeable;
import java.util.List;

import com.ibm.etcd.client.kv.KvClient;
import com.ibm.etcd.client.lease.LeaseClient;
Expand Down Expand Up @@ -44,4 +45,7 @@ public interface KvStoreClient extends Closeable {
*/
PersistentLease getSessionLease();

void updateCredentials(String name, String password);

List<String> getCredentials();
}