Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,25 @@ public CriteriaResponse executeCriteriaService(final Switcher switcher, final St
.queryParam(Switcher.KEY, switcher.getSwitcherKey())
.queryParam(Switcher.SHOW_REASON, switcher.isShowReason())
.queryParam(Switcher.BYPASS_METRIC, switcher.isBypassMetrics());

final Response response = myResource.request(MediaType.APPLICATION_JSON)
.header(HEADER_AUTHORIZATION, String.format(TOKEN_TEXT, token))
.post(Entity.json(switcher.getInputRequest()));

if (response.getStatus() == 200) {
final CriteriaResponse criteriaResponse = response.readEntity(CriteriaResponse.class);
criteriaResponse.setSwitcherKey(switcher.getSwitcherKey());
criteriaResponse.setEntry(switcher.getEntry());
response.close();
try {
final Response response = myResource.request(MediaType.APPLICATION_JSON)
.header(HEADER_AUTHORIZATION, String.format(TOKEN_TEXT, token))
.post(Entity.json(switcher.getInputRequest()));

return criteriaResponse;
}
if (response.getStatus() == 200) {
final CriteriaResponse criteriaResponse = response.readEntity(CriteriaResponse.class);
criteriaResponse.setSwitcherKey(switcher.getSwitcherKey());
criteriaResponse.setEntry(switcher.getEntry());
response.close();

throw new SwitcherRemoteException(url, response.getStatus());
return criteriaResponse;
}

throw new SwitcherRemoteException(url, response.getStatus());
} catch (Exception e) {
throw new SwitcherRemoteException(url, e);
}
}

@Override
Expand All @@ -85,19 +89,23 @@ public Optional<AuthResponse> auth() {

final String url = SwitcherContextBase.contextStr(ContextKey.URL);
final WebTarget myResource = client.target(String.format(AUTH_URL, url));

final Response response = myResource.request(MediaType.APPLICATION_JSON)
.header(HEADER_APIKEY, SwitcherContextBase.contextStr(ContextKey.APIKEY))
.post(Entity.json(authRequest));

if (response.getStatus() == 200) {
Optional<AuthResponse> authResponse = Optional.of(response.readEntity(AuthResponse.class));
response.close();
try {
final Response response = myResource.request(MediaType.APPLICATION_JSON)
.header(HEADER_APIKEY, SwitcherContextBase.contextStr(ContextKey.APIKEY))
.post(Entity.json(authRequest));

return authResponse;
}
if (response.getStatus() == 200) {
Optional<AuthResponse> authResponse = Optional.of(response.readEntity(AuthResponse.class));
response.close();

throw new SwitcherRemoteException(url, response.getStatus());
return authResponse;
}

throw new SwitcherRemoteException(url, response.getStatus());
} catch (Exception e) {
throw new SwitcherRemoteException(url, e);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.github.switcherapi.client.service.remote;

import java.util.Date;
import java.util.Optional;
import java.util.Set;

import com.github.switcherapi.client.SwitcherContextBase;
import com.github.switcherapi.client.exception.SwitcherRemoteException;
import com.github.switcherapi.client.exception.SwitcherException;
import com.github.switcherapi.client.exception.SwitcherInvalidDateTimeArgumentException;
import com.github.switcherapi.client.exception.SwitcherRemoteException;
import com.github.switcherapi.client.model.ContextKey;
import com.github.switcherapi.client.model.Switcher;
import com.github.switcherapi.client.model.criteria.Snapshot;
Expand All @@ -19,100 +15,118 @@
import com.github.switcherapi.client.remote.ClientWSImpl;
import com.github.switcherapi.client.utils.SwitcherUtils;

import java.util.Date;
import java.util.Optional;
import java.util.Set;

/**
* @author Roger Floriano (petruki)
* @since 2019-12-24
*/
public class ClientRemoteService {

private static ClientRemoteService instance;

private final ClientWS clientWs;

private Optional<AuthResponse> authResponse = Optional.empty();
private AuthResponse authResponse;

private enum TokenStatus {
VALID, INVALID, SILENT
}

private enum Singleton {
INSTANCE;

private final ClientRemoteService instance = new ClientRemoteService();

public ClientRemoteService getInstance() {
return this.instance;
}
}

private ClientRemoteService() {
this.clientWs = new ClientWSImpl();
}

public static ClientRemoteService getInstance() {
if (instance == null) {
instance = new ClientRemoteService();
}
return instance;
return Singleton.INSTANCE.getInstance();
}

public CriteriaResponse executeCriteria(final Switcher switcher) {
if (!this.isTokenValid()) {
this.auth();
final TokenStatus tokenStatus = this.isTokenValid();

try {
this.auth(tokenStatus);

return this.clientWs.executeCriteriaService(switcher,
Optional.of(this.authResponse).orElseGet(AuthResponse::new).getToken());
} catch (final SwitcherRemoteException e) {
if (tokenStatus != TokenStatus.SILENT) {
this.setSilentModeExpiration();
}

throw e;
}

return this.clientWs.executeCriteriaService(
switcher, this.authResponse.get().getToken());
}

public Snapshot resolveSnapshot() throws SwitcherException {
if (!this.isTokenValid()) {
this.auth();
}
this.auth(this.isTokenValid());

return this.clientWs.resolveSnapshot(
this.authResponse.orElseGet(AuthResponse::new).getToken());
Optional.of(this.authResponse).orElseGet(AuthResponse::new).getToken());
}

public boolean checkSnapshotVersion(final long version) {
if (!this.isTokenValid()) {
this.auth();
}

final SnapshotVersionResponse snapshotVersionResponse = this.clientWs.checkSnapshotVersion(version,
this.authResponse.orElseGet(AuthResponse::new).getToken());
this.auth(this.isTokenValid());

final SnapshotVersionResponse snapshotVersionResponse = this.clientWs.checkSnapshotVersion(version,
Optional.of(this.authResponse).orElseGet(AuthResponse::new).getToken());

return snapshotVersionResponse.isUpdated();
}

public SwitchersCheck checkSwitchers(final Set<String> switchers) {
final TokenStatus tokenStatus = this.isTokenValid();

try {
if (!this.isTokenValid()) {
this.auth();
this.auth(tokenStatus);

return this.clientWs.checkSwitchers(switchers,
Optional.of(this.authResponse).orElseGet(AuthResponse::new).getToken());
} catch (final SwitcherRemoteException e) {
if (tokenStatus != TokenStatus.SILENT) {
this.setSilentModeExpiration();
}

return this.clientWs.checkSwitchers(switchers,
this.authResponse.orElseGet(AuthResponse::new).getToken());
} catch (final Exception e) {
throw new SwitcherRemoteException(SwitcherContextBase.contextStr(ContextKey.URL), e);

throw e;
}
}

private void auth() {
try {
this.authResponse = this.clientWs.auth();
} catch (final SwitcherException e) {
throw e;
} catch (final Exception e) {
this.setSilentModeExpiration();
throw new SwitcherRemoteException(SwitcherContextBase.contextStr(ContextKey.URL), e);

private void auth(TokenStatus tokenStatus) {
if (tokenStatus == TokenStatus.INVALID) {
this.authResponse = this.clientWs.auth().orElseGet(AuthResponse::new);
}

if (tokenStatus == TokenStatus.SILENT) {
throw new SwitcherRemoteException(SwitcherContextBase.contextStr(ContextKey.URL));
}
}

private boolean isTokenValid() throws SwitcherRemoteException,
private TokenStatus isTokenValid() throws SwitcherRemoteException,
SwitcherInvalidDateTimeArgumentException {

if (this.authResponse.isPresent()) {
if (this.authResponse.get().getToken().equals(ContextKey.SILENT_MODE.getParam())
&& !this.authResponse.get().isExpired()) {
throw new SwitcherRemoteException(SwitcherContextBase.contextStr(ContextKey.URL));
} else {
if (!this.clientWs.isAlive()) {
this.setSilentModeExpiration();
throw new SwitcherRemoteException(SwitcherContextBase.contextStr(ContextKey.URL));
}

return !this.authResponse.orElseGet(AuthResponse::new).isExpired();
}

final Optional<AuthResponse> optAuthResponse = Optional.ofNullable(this.authResponse);

if (optAuthResponse.isEmpty()) {
return TokenStatus.INVALID;
}

return false;

if (optAuthResponse.get().getToken().equals(ContextKey.SILENT_MODE.getParam())
&& !optAuthResponse.get().isExpired()) {
return TokenStatus.SILENT;
}

return optAuthResponse.orElseGet(AuthResponse::new).isExpired() ?
TokenStatus.INVALID : TokenStatus.VALID;
}

private void setSilentModeExpiration() throws SwitcherInvalidDateTimeArgumentException {
Expand All @@ -122,12 +136,12 @@ private void setSilentModeExpiration() throws SwitcherInvalidDateTimeArgumentExc

response.setToken(ContextKey.SILENT_MODE.getParam());
response.setExp(SwitcherUtils.addTimeDuration(addValue, new Date()).getTime()/1000);
this.authResponse = Optional.of(response);
this.authResponse = response;
}
}

public void clearAuthResponse() {
this.authResponse = Optional.empty();
this.authResponse = null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,6 @@ void shouldReturnTrue_tokenExpired() throws InterruptedException {
CountDownLatch waiter = new CountDownLatch(1);
waiter.await(2, TimeUnit.SECONDS);

//isAlive
givenResponse(generateStatusResponse("200"));

//auth
givenResponse(generateMockAuth(2));

Expand All @@ -338,9 +335,6 @@ void shouldValidateAndUpdateSnapshot() {
//criteria/snapshot_check
givenResponse(generateCheckSnapshotVersionResponse("false"));

//auth isAlive
givenResponse(generateMockAuth(10));

//graphql
givenResponse(generateSnapshotResponse());

Expand Down Expand Up @@ -438,9 +432,6 @@ void shouldValidateAndLoadSnapshot_whenOffline() {
//criteria/snapshot_check
givenResponse(generateCheckSnapshotVersionResponse("false"));

//auth isAlive
givenResponse(generateMockAuth(10));

//graphql
givenResponse(generateSnapshotResponse());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,6 @@ private void givenSnapshotUpdateResponse(boolean isUpdated) {
givenResponse(generateCheckSnapshotVersionResponse(Boolean.toString(isUpdated)));

if (!isUpdated) {
//auth isAlive
givenResponse(generateMockAuth());

//graphql
givenResponse(generateSnapshotResponse("default.json"));
}
Expand Down Expand Up @@ -215,12 +212,10 @@ void shouldNotUpdateSnapshot_whenNoUpdateAvailable() throws InterruptedException
@Order(4)
void shouldUpdateSnapshot_online_inMemory() throws InterruptedException {
//given
//load snapshot in-memory
givenResponse(generateMockAuth()); //auth
givenResponse(generateSnapshotResponse("default_outdated.json")); //graphql

//update snapshot
givenSnapshotUpdateResponse(false);
givenResponse(generateCheckSnapshotVersionResponse(Boolean.toString(false))); //criteria/snapshot_check
givenResponse(generateSnapshotResponse("default.json")); //graphql

//that
Switchers.configure(ContextBuilder.builder()
Expand Down