Skip to content

Commit 7b0a410

Browse files
authored
Merge pull request #184 from splitio/factory-instantiation-service
[Lucas] Factory instantiation service
2 parents 43debcb + 30d1a4c commit 7b0a410

File tree

3 files changed

+120
-18
lines changed

3 files changed

+120
-18
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.split.client;
2+
3+
import com.google.common.annotations.VisibleForTesting;
4+
import com.google.common.collect.ConcurrentHashMultiset;
5+
import com.google.common.collect.Multiset;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
public class ApiKeyCounter {
10+
11+
private static final Logger _log = LoggerFactory.getLogger(ApiKeyCounter.class);
12+
private static final Multiset<String> USED_API_KEYS = ConcurrentHashMultiset.create();
13+
14+
private ApiKeyCounter() {}
15+
16+
public static ApiKeyCounter getApiKeyCounterInstance() {
17+
return ApyKeyCounterHolder.INSTANCE;
18+
}
19+
20+
//Inner class to provide instance of class
21+
private static class ApyKeyCounterHolder
22+
{
23+
private static final ApiKeyCounter INSTANCE = new ApiKeyCounter();
24+
}
25+
26+
public void add(String apiKey) {
27+
String message;
28+
if (USED_API_KEYS.contains(apiKey)) {
29+
message = String.format("factory instantiation: You already have %s with this API Key. " +
30+
"We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing " +
31+
"it throughout your application.",
32+
USED_API_KEYS.count(apiKey) == 1 ? "1 factory" : String.format("%s factories", USED_API_KEYS.count(apiKey)));
33+
_log.warn(message);
34+
} else if (!USED_API_KEYS.isEmpty()) {
35+
message = "factory instantiation: You already have an instance of the Split factory. " +
36+
"Make sure you definitely want this additional instance. We recommend keeping only one instance of " +
37+
"the factory at all times (Singleton pattern) and reusing it throughout your application.“";
38+
_log.warn(message);
39+
}
40+
USED_API_KEYS.add(apiKey);
41+
}
42+
43+
public void remove(String apiKey) {
44+
USED_API_KEYS.remove(apiKey);
45+
}
46+
47+
/**
48+
* Just for test
49+
* @param apiKey
50+
* @return
51+
*/
52+
@VisibleForTesting
53+
boolean isApiKeyPresent(String apiKey) {
54+
return USED_API_KEYS.contains(apiKey);
55+
}
56+
57+
/**
58+
* Just for test
59+
* @param apiKey
60+
* @return
61+
*/
62+
@VisibleForTesting
63+
int getCount(String apiKey) {
64+
return USED_API_KEYS.count(apiKey);
65+
}
66+
}

client/src/main/java/io/split/client/SplitFactoryImpl.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.split.client;
22

3-
import com.google.common.collect.ConcurrentHashMultiset;
4-
import com.google.common.collect.Multiset;
53
import io.split.client.impressions.AsynchronousImpressionListener;
64
import io.split.client.impressions.ImpressionListener;
75
import io.split.client.impressions.ImpressionsManagerImpl;
@@ -62,31 +60,19 @@ public class SplitFactoryImpl implements SplitFactory {
6260
private final static long SSE_CONNECT_TIMEOUT = 30000;
6361
private final static long SSE_SOCKET_TIMEOUT = 70000;
6462

65-
private static final Multiset<String> USED_API_TOKENS = ConcurrentHashMultiset.create();
6663
private static Random RANDOM = new Random();
6764

6865
private final SplitClient _client;
6966
private final SplitManager _manager;
7067
private final Runnable destroyer;
7168
private final String _apiToken;
7269
private boolean isTerminated = false;
70+
private final ApiKeyCounter _apiKeyCounter;
7371

7472
public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyntaxException {
7573
_apiToken = apiToken;
76-
77-
if (USED_API_TOKENS.contains(apiToken)) {
78-
String message = String.format("factory instantiation: You already have %s with this API Key. " +
79-
"We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing " +
80-
"it throughout your application.",
81-
USED_API_TOKENS.count(apiToken) == 1 ? "1 factory" : String.format("%s factories", USED_API_TOKENS.count(apiToken)));
82-
_log.warn(message);
83-
} else if (!USED_API_TOKENS.isEmpty()) {
84-
String message = "factory instantiation: You already have an instance of the Split factory. " +
85-
"Make sure you definitely want this additional instance. We recommend keeping only one instance of " +
86-
"the factory at all times (Singleton pattern) and reusing it throughout your application.“";
87-
_log.warn(message);
88-
}
89-
USED_API_TOKENS.add(apiToken);
74+
_apiKeyCounter = ApiKeyCounter.getApiKeyCounterInstance();
75+
_apiKeyCounter.add(apiToken);
9076

9177
if (config.blockUntilReady() == -1) {
9278
//BlockUntilReady not been set
@@ -214,7 +200,7 @@ public void destroy() {
214200
synchronized (SplitFactoryImpl.class) {
215201
if (!isTerminated) {
216202
destroyer.run();
217-
USED_API_TOKENS.remove(_apiToken);
203+
_apiKeyCounter.remove(_apiToken);
218204
isTerminated = true;
219205
}
220206
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.split.client;
2+
3+
import junit.framework.TestCase;
4+
import org.junit.Test;
5+
6+
public class ApiKeyCounterTest extends TestCase {
7+
8+
private static final String FIRST_KEY = "KEYNUMBER1";
9+
private static final String SECOND_KEY = "KEYNUMBER2";
10+
11+
@Test
12+
public void testAddingNewToken() {
13+
ApiKeyCounter.getApiKeyCounterInstance().add(FIRST_KEY);
14+
assertTrue(ApiKeyCounter.getApiKeyCounterInstance().isApiKeyPresent(FIRST_KEY));
15+
16+
ApiKeyCounter.getApiKeyCounterInstance().remove(FIRST_KEY);
17+
}
18+
19+
@Test
20+
public void testAddingExistingToken() {
21+
ApiKeyCounter.getApiKeyCounterInstance().add(FIRST_KEY);
22+
ApiKeyCounter.getApiKeyCounterInstance().add(FIRST_KEY);
23+
24+
assertTrue(ApiKeyCounter.getApiKeyCounterInstance().isApiKeyPresent(FIRST_KEY));
25+
assertEquals(2, ApiKeyCounter.getApiKeyCounterInstance().getCount(FIRST_KEY));
26+
ApiKeyCounter.getApiKeyCounterInstance().remove(FIRST_KEY);
27+
ApiKeyCounter.getApiKeyCounterInstance().remove(FIRST_KEY);
28+
}
29+
30+
@Test
31+
public void testRemovingToken() {
32+
ApiKeyCounter.getApiKeyCounterInstance().add(FIRST_KEY);
33+
ApiKeyCounter.getApiKeyCounterInstance().remove(FIRST_KEY);
34+
35+
assertFalse(ApiKeyCounter.getApiKeyCounterInstance().isApiKeyPresent(FIRST_KEY));
36+
assertEquals(0, ApiKeyCounter.getApiKeyCounterInstance().getCount(FIRST_KEY));
37+
}
38+
39+
@Test
40+
public void testAddingNonExistingToken() {
41+
ApiKeyCounter.getApiKeyCounterInstance().add(FIRST_KEY);
42+
ApiKeyCounter.getApiKeyCounterInstance().add(SECOND_KEY);
43+
44+
assertTrue(ApiKeyCounter.getApiKeyCounterInstance().isApiKeyPresent(FIRST_KEY));
45+
assertEquals(1, ApiKeyCounter.getApiKeyCounterInstance().getCount(FIRST_KEY));
46+
assertEquals(1, ApiKeyCounter.getApiKeyCounterInstance().getCount(SECOND_KEY));
47+
ApiKeyCounter.getApiKeyCounterInstance().remove(FIRST_KEY);
48+
ApiKeyCounter.getApiKeyCounterInstance().remove(SECOND_KEY);
49+
}
50+
}

0 commit comments

Comments
 (0)