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
23 changes: 11 additions & 12 deletions src/main/java/com/github/switcherapi/client/SwitcherExecutor.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package com.github.switcherapi.client;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.github.switcherapi.client.exception.SwitcherRemoteException;
import com.github.switcherapi.client.exception.SwitcherSnapshotWriteException;
import com.github.switcherapi.client.model.ContextKey;
import com.github.switcherapi.client.model.Switcher;
import com.github.switcherapi.client.model.criteria.Domain;
import com.github.switcherapi.client.model.criteria.Snapshot;
import com.github.switcherapi.client.model.response.CriteriaResponse;
import com.github.switcherapi.client.service.remote.ClientRemoteService;
import com.github.switcherapi.client.service.remote.ClientRemote;
import com.github.switcherapi.client.utils.SnapshotEventHandler;
import com.github.switcherapi.client.utils.SnapshotLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* The Executor provides an API to handle Remote and Local functionalities that
Expand Down Expand Up @@ -75,25 +74,25 @@ public abstract class SwitcherExecutor {
*/
public abstract long getSnapshotVersion();

protected boolean checkSnapshotVersion(final Domain domain) {
protected boolean checkSnapshotVersion(ClientRemote clientRemote, final Domain domain) {
final String environment = SwitcherContextBase.contextStr(ContextKey.ENVIRONMENT);

if (logger.isDebugEnabled()) {
logger.debug(String.format("verifying snapshot version - environment: %s", environment));
}

return ClientRemoteService.getInstance().checkSnapshotVersion(domain.getVersion());
return clientRemote.checkSnapshotVersion(domain.getVersion());
}

protected Domain initializeSnapshotFromAPI() {
protected Domain initializeSnapshotFromAPI(ClientRemote clientRemote) {
final String environment = SwitcherContextBase.contextStr(ContextKey.ENVIRONMENT);

if (logger.isDebugEnabled()) {
logger.debug(String.format("initializing snapshot from API - environment: %s", environment));
}

try {
final Snapshot snapshot = ClientRemoteService.getInstance().resolveSnapshot();
final Snapshot snapshot = clientRemote.resolveSnapshot();
final String snapshotLocation = SwitcherContextBase.contextStr(ContextKey.SNAPSHOT_LOCATION);

if (snapshotLocation != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public String getEnvironment() {
}

public void setEnvironment(String environment) {
if (!StringUtils.isBlank(environment)) {
if (StringUtils.isNotBlank(environment)) {
this.environment = environment;
} else {
this.environment = DEFAULT_ENV;
Expand Down Expand Up @@ -162,7 +162,7 @@ public String getRegexTimeout() {
}

public void setRegexTimeout(String regexTimeout) {
if (!StringUtils.isBlank(regexTimeout)) {
if (StringUtils.isNotBlank(regexTimeout)) {
this.regexTimeout = regexTimeout;
} else {
this.regexTimeout = DEFAULT_REGEX_TIMEOUT;
Expand Down Expand Up @@ -222,7 +222,7 @@ public String getTimeoutMs() {
}

public void setTimeoutMs(String timeoutMs) {
if (!StringUtils.isBlank(timeoutMs)) {
if (StringUtils.isNotBlank(timeoutMs)) {
this.timeoutMs = timeoutMs;
} else {
this.timeoutMs = DEFAULT_TIMEOUT_MS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public final class Switcher extends SwitcherBuilder {
* Use {@link SwitcherContext#getSwitcher(String)} to create this object.
*
* @param switcherKey name of the key created
* @param context configuration object containing all information to start using switchers
* @param context client context in which the switcher will be executed (local/remote)
*/
public Switcher(final String switcherKey, final SwitcherExecutor context) {
this.switcherKey = switcherKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.github.switcherapi.client.model.Switcher;
import com.github.switcherapi.client.model.criteria.Domain;
import com.github.switcherapi.client.model.response.CriteriaResponse;
import com.github.switcherapi.client.service.remote.ClientRemote;
import com.github.switcherapi.client.service.remote.ClientRemoteService;
import com.github.switcherapi.client.utils.SnapshotEventHandler;
import com.github.switcherapi.client.utils.SnapshotLoader;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -26,10 +28,13 @@
public class SwitcherLocalService extends SwitcherExecutor {

private static final Logger logger = LogManager.getLogger(SwitcherLocalService.class);

private final ClientRemote clientRemote;

private Domain domain;

public SwitcherLocalService() {
this.clientRemote = new ClientRemoteService();
this.init();
}

Expand All @@ -44,13 +49,13 @@ public void init() {
final boolean snapshotAutoload = SwitcherContextBase.contextBol(ContextKey.SNAPSHOT_AUTO_LOAD);

if (StringUtils.isBlank(snapshotLocation) && snapshotAutoload) {
this.domain = this.initializeSnapshotFromAPI();
this.domain = this.initializeSnapshotFromAPI(this.clientRemote);
} else if (StringUtils.isNotBlank(snapshotLocation)) {
try {
this.domain = SnapshotLoader.loadSnapshot(snapshotLocation, environment);
} catch (IOException e) {
if (snapshotAutoload) {
this.domain = this.initializeSnapshotFromAPI();
this.domain = this.initializeSnapshotFromAPI(this.clientRemote);
}
}
}
Expand All @@ -74,12 +79,12 @@ public CriteriaResponse executeCriteria(final Switcher switcher) {

@Override
public boolean checkSnapshotVersion() {
return super.checkSnapshotVersion(this.domain);
return super.checkSnapshotVersion(this.clientRemote, this.domain);
}

@Override
public void updateSnapshot() {
this.domain = super.initializeSnapshotFromAPI();
this.domain = super.initializeSnapshotFromAPI(this.clientRemote);
}

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

import com.github.switcherapi.client.exception.SwitcherException;
import com.github.switcherapi.client.model.Switcher;
import com.github.switcherapi.client.model.criteria.Snapshot;
import com.github.switcherapi.client.model.criteria.SwitchersCheck;
import com.github.switcherapi.client.model.response.CriteriaResponse;

import java.util.Set;

/**
* @author Roger Floriano (petruki)
* @since 2023-07-12
*/
public interface ClientRemote {

CriteriaResponse executeCriteria(final Switcher switcher);

Snapshot resolveSnapshot() throws SwitcherException;

boolean checkSnapshotVersion(final long version);

SwitchersCheck checkSwitchers(final Set<String> switchers);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author Roger Floriano (petruki)
* @since 2019-12-24
*/
public class ClientRemoteService {
public class ClientRemoteService implements ClientRemote {

private final ClientWS clientWs;

Expand All @@ -33,25 +33,12 @@ public class ClientRemoteService {
private enum TokenStatus {
VALID, INVALID, SILENT
}

private enum Singleton {
INSTANCE;

private final ClientRemoteService instance = new ClientRemoteService();

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

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

public static ClientRemoteService getInstance() {
return Singleton.INSTANCE.getInstance();
}


@Override
public CriteriaResponse executeCriteria(final Switcher switcher) {
final TokenStatus tokenStatus = this.isTokenValid();

Expand All @@ -69,13 +56,15 @@ public CriteriaResponse executeCriteria(final Switcher switcher) {
}
}

@Override
public Snapshot resolveSnapshot() throws SwitcherException {
this.auth(this.isTokenValid());

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


@Override
public boolean checkSnapshotVersion(final long version) {
this.auth(this.isTokenValid());

Expand All @@ -84,7 +73,8 @@ public boolean checkSnapshotVersion(final long version) {

return snapshotVersionResponse.isUpdated();
}


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

Expand Down Expand Up @@ -141,8 +131,4 @@ private void setSilentModeExpiration() throws SwitcherInvalidDateTimeArgumentExc
}
}

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ public class SwitcherRemoteService extends SwitcherExecutor {
private static final Logger logger = LogManager.getLogger(SwitcherRemoteService.class);

private final SwitcherLocalService switcherOffline;

private final ClientRemote clientRemote;

public SwitcherRemoteService() {
this.switcherOffline = new SwitcherLocalService();
this.clientRemote = new ClientRemoteService();
}

@Override
Expand All @@ -39,7 +42,7 @@ public CriteriaResponse executeCriteria(final Switcher switcher) {
}

try {
final CriteriaResponse response = ClientRemoteService.getInstance().executeCriteria(switcher);
final CriteriaResponse response = this.clientRemote.executeCriteria(switcher);

if (logger.isDebugEnabled()) {
logger.debug(String.format("[Online] response: %s", response));
Expand Down Expand Up @@ -70,16 +73,16 @@ private CriteriaResponse executeSilentCriteria(final Switcher switcher,
public boolean checkSnapshotVersion() {
if (StringUtils.isNotBlank(SwitcherContextBase.contextStr(ContextKey.SNAPSHOT_LOCATION))
&& this.switcherOffline.getDomain() != null) {
return super.checkSnapshotVersion(this.switcherOffline.getDomain());
return super.checkSnapshotVersion(this.clientRemote, this.switcherOffline.getDomain());
}

super.initializeSnapshotFromAPI();
super.initializeSnapshotFromAPI(this.clientRemote);
return Boolean.TRUE;
}

@Override
public void updateSnapshot() {
this.switcherOffline.setDomain(super.initializeSnapshotFromAPI());
this.switcherOffline.setDomain(super.initializeSnapshotFromAPI(this.clientRemote));
}

@Override
Expand All @@ -88,7 +91,7 @@ public void checkSwitchers(final Set<String> switchers) {
logger.debug(String.format("switchers: %s", switchers));
}

final SwitchersCheck response = ClientRemoteService.getInstance().checkSwitchers(switchers);
final SwitchersCheck response = this.clientRemote.checkSwitchers(switchers);
if (response.getNotFound() != null && response.getNotFound().length > 0) {
throw new SwitchersValidationException(Arrays.toString(response.getNotFound()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,36 @@
import com.github.switcherapi.Switchers;
import com.github.switcherapi.client.exception.SwitcherRemoteException;
import com.github.switcherapi.client.model.Switcher;
import com.github.switcherapi.client.remote.ClientWSImpl;
import com.github.switcherapi.client.service.remote.ClientRemoteService;
import com.github.switcherapi.client.utils.SwitcherUtils;
import mockwebserver3.MockResponse;
import mockwebserver3.MockWebServer;
import com.github.switcherapi.fixture.MockWebServerHelper;
import mockwebserver3.QueueDispatcher;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Date;

import static org.junit.jupiter.api.Assertions.assertThrows;

class SwitcherApiMock2Test {

private static MockWebServer mockBackEnd;
class SwitcherApiMock2Test extends MockWebServerHelper {

@BeforeAll
static void setup() throws IOException {
mockBackEnd = new MockWebServer();
mockBackEnd.start();
((QueueDispatcher) mockBackEnd.getDispatcher()).setFailFast(true);

Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
Switchers.initializeClient();
MockWebServerHelper.setupMockServer();

Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
Switchers.initializeClient();
}

@AfterAll
static void tearDown() throws IOException {
mockBackEnd.shutdown();
MockWebServerHelper.tearDownMockServer();
}

@BeforeEach
void resetSwitcherContextState() {
((QueueDispatcher) mockBackEnd.getDispatcher()).clear();
ClientRemoteService.getInstance().clearAuthResponse();

Switchers.configure(ContextBuilder.builder()
.offlineMode(false)
Expand All @@ -55,34 +45,6 @@ void resetSwitcherContextState() {

Switchers.initializeClient();
}

/**
* @see ClientWSImpl#auth()
*
* @param secondsAhead time to expire the token
* @return Generated mock /auth response
*/
private MockResponse generateMockAuth(int secondsAhead) {
return new MockResponse()
.setBody(String.format("{ \"token\": \"%s\", \"exp\": \"%s\" }",
"mocked_token", SwitcherUtils.addTimeDuration(secondsAhead + "s", new Date()).getTime()/1000))
.addHeader("Content-Type", "application/json");
}

/**
* @see ClientWSImpl#isAlive()
*
* @param code HTTP status
* @return Generated mock /check response
*/
private MockResponse generateStatusResponse(String code) {
return new MockResponse().setStatus(String.format("HTTP/1.1 %s", code));

}

private void givenResponse(MockResponse response) {
((QueueDispatcher) mockBackEnd.getDispatcher()).enqueueResponse(response);
}

@Test
void shouldReturnError_componentNotRegistered() {
Expand Down
Loading