Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
2b4f178
added EvaluatorImp and cleanup code from splitclientImp
sanzmauro Nov 27, 2020
61ee728
added UT
sanzmauro Dec 8, 2020
71b3fe5
Merge pull request #172 from splitio/evaluator-polishing-ut
sanzmauro Dec 8, 2020
495332f
cleaning sonarqube warnings
sanzmauro Dec 8, 2020
895dca1
cleaning code
sanzmauro Dec 8, 2020
e10331c
wip
sanzmauro Dec 8, 2020
166146b
pr feedback
sanzmauro Dec 8, 2020
9130bb7
Merge pull request #173 from splitio/add-evaluator-implementation
sanzmauro Dec 8, 2020
9cabb70
Matchers refactor
sanzmauro Dec 8, 2020
4f104b9
Merge pull request #174 from splitio/dependecy-matcher-refactor
sanzmauro Dec 8, 2020
af68d6a
added splitCache and splitFetcher refactor
sanzmauro Dec 9, 2020
0bc7d56
traffic type exists refactor
sanzmauro Dec 10, 2020
1c45e77
pr feedback
sanzmauro Dec 11, 2020
f3d0ddb
Merge pull request #175 from splitio/split-fetcher-refactor-storage
sanzmauro Dec 11, 2020
f78a355
renamed provider to task and refactor
sanzmauro Dec 10, 2020
9aded16
wip
sanzmauro Dec 11, 2020
9eb18e5
wip
sanzmauro Dec 11, 2020
f0d0bc6
pr feedback
sanzmauro Dec 16, 2020
b698c90
rename and refactor
sanzmauro Dec 15, 2020
e30b7b0
pr feedback
sanzmauro Dec 16, 2020
d3f672d
Merge pull request #177 from splitio/cache-move-package-and-rename
sanzmauro Dec 16, 2020
76669cd
Merge pull request #176 from splitio/split-fetcher-refactor-task
sanzmauro Dec 16, 2020
7367ceb
input validation refactor
sanzmauro Dec 15, 2020
ba6f604
add uts
sanzmauro Dec 15, 2020
d3f9360
fixed build
sanzmauro Dec 16, 2020
5e1e63c
feedback
sanzmauro Dec 17, 2020
ddff5f3
renamed metric label
sanzmauro Dec 17, 2020
5ff4607
pr feedback
sanzmauro Dec 17, 2020
cc25ae0
Decouple of segment storage. Segment Cache implementation.
ldecheverz-split Dec 18, 2020
646cfd3
Merge branch 'evaluator-refactor' of https://github.com/splitio/java-…
ldecheverz-split Dec 18, 2020
452c105
Relocation of files to new cache folder.
ldecheverz-split Dec 18, 2020
0c98764
wip
sanzmauro Dec 18, 2020
25b6872
pr feedback
sanzmauro Dec 21, 2020
6e4f77e
manager refactor
sanzmauro Dec 18, 2020
897eb5d
Merge pull request #179 from splitio/split-manager-refactor
sanzmauro Dec 21, 2020
a68dee1
Merge pull request #178 from splitio/input-validation-refactor
sanzmauro Dec 21, 2020
9842ab5
Update of RefreshableSegment and UT
ldecheverz-split Dec 21, 2020
78c5807
Merge branch 'segment-storage-mauro' of github.com:splitio/java-clien…
ldecheverz-split Dec 21, 2020
f1bd3fc
Merge branch 'evaluator-refactor' of github.com:splitio/java-client i…
ldecheverz-split Dec 21, 2020
2330cff
Fixes on tests and final refactor.
ldecheverz-split Jan 5, 2021
0b57206
PR comments fixed
ldecheverz-split Jan 7, 2021
1d6bc4b
Deleting deprecated Tests Classes.
ldecheverz-split Jan 8, 2021
9aea623
Last suggestion Fixed
ldecheverz-split Jan 8, 2021
da9d743
Fixing sonarqube errors
ldecheverz-split Jan 11, 2021
43debcb
Merge pull request #180 from splitio/decouple-segment-storage
sanzmauro Jan 12, 2021
e1a6d9c
Creating FactoryInstantiationService
ldecheverz-split Jan 12, 2021
7d06995
Adding files were forgotten in last commit
ldecheverz-split Jan 12, 2021
c9a6da1
Merge branch 'evaluator-refactor' of github.com:splitio/java-client i…
ldecheverz-split Jan 12, 2021
d61a8fb
Final commit, editing name and adding some key words
ldecheverz-split Jan 12, 2021
df28d84
Fixing PR comments
ldecheverz-split Jan 13, 2021
97e604f
Deleting 'volatile'
ldecheverz-split Jan 13, 2021
86c473e
Changing the way the getInstance is synchronized
ldecheverz-split Jan 13, 2021
e97c7cc
Changing the sinchronization. Last time
ldecheverz-split Jan 13, 2021
30d1a4c
Fix white space
ldecheverz-split Jan 13, 2021
7b0a410
Merge pull request #184 from splitio/factory-instantiation-service
sanzmauro Jan 13, 2021
d8adbf5
cleanup
sanzmauro Jan 8, 2021
041d12b
Factory code cleanup
sanzmauro Jan 11, 2021
4bee2e3
Revert "Factory code cleanup"
sanzmauro Jan 11, 2021
336a708
pr feedback
sanzmauro Jan 14, 2021
5e57a56
pr feedback
sanzmauro Jan 14, 2021
a9ca51e
pr feedbakc
sanzmauro Jan 14, 2021
f192608
Merge pull request #181 from splitio/factory-cleanup
sanzmauro Jan 14, 2021
6efce1b
Factory code cleanup
sanzmauro Jan 11, 2021
26d01fc
added tests - wip
sanzmauro Jan 11, 2021
bd5195d
added integration tests
sanzmauro Jan 12, 2021
8a4b97e
Merge pull request #182 from splitio/localhost-code-cleanup
sanzmauro Jan 14, 2021
1b234ae
Merge pull request #183 from splitio/evaluator-integration-tests
sanzmauro Jan 18, 2021
dbb3100
Adding test to increment Coverage
ldecheverz-split Jan 18, 2021
10bdfc0
Merge pull request #185 from splitio/split-factory-tests
NicoZelaya Jan 28, 2021
6644f74
LocalhostSplitClient updated
ldecheverz-split Feb 9, 2021
4a47806
Adding double check.
ldecheverz-split Feb 22, 2021
de128d1
Using SplitClientImpl instead LocalhostSplitClient in LocalhostFactory
ldecheverz-split Feb 23, 2021
9201e2a
Forgot to change this previous change. SplitCache in SplitClientImpl …
ldecheverz-split Feb 23, 2021
efdc30d
Fixing typo
ldecheverz-split Feb 24, 2021
faf570e
Merge pull request #188 from splitio/localhost-client-refactor
ldecheverz-split Feb 24, 2021
90b3d03
Double Checking at first event
ldecheverz-split Feb 25, 2021
d7f9b52
Tests and final fix
ldecheverz-split Mar 9, 2021
563216a
Merge pull request #190 from splitio/evaluator-refactor
ldecheverz-split Mar 9, 2021
edf3f3d
Adding second region
ldecheverz-split Mar 9, 2021
bf996e2
Adding test case
ldecheverz-split Mar 9, 2021
c91a8fa
Merge pull request #191 from splitio/occupancy-sec-reg
ldecheverz-split Mar 10, 2021
e10449f
Merge branch 'development' of github.com:splitio/java-client into con…
ldecheverz-split Mar 10, 2021
ce08d80
Pulling develompent's changes
ldecheverz-split Mar 10, 2021
a81e171
Optimizing imports
ldecheverz-split Mar 10, 2021
3befc2b
Adding changes on syncAll, tests and fixing some things that were wrong
ldecheverz-split Mar 16, 2021
4529f81
Fixing PR comments
ldecheverz-split Mar 16, 2021
daea082
Fixing mistake
ldecheverz-split Mar 18, 2021
357af67
FIxing PR comments
ldecheverz-split Mar 18, 2021
a79cfd1
Fixing travis failed
ldecheverz-split Mar 18, 2021
aa43301
Travis issue
ldecheverz-split Mar 18, 2021
ad75990
Merge pull request #192 from splitio/connection-confirmation-first-event
ldecheverz-split Mar 18, 2021
c017e99
Merge branch 'development' of github.com:splitio/java-client into cac…
ldecheverz-split Mar 18, 2021
fdba632
Merge pull request #193 from splitio/cache-update
ldecheverz-split Mar 19, 2021
316c0f6
Releasing 4.1.4
ldecheverz-split Mar 19, 2021
08b9754
Merge pull request #194 from splitio/release-4.1.4
ldecheverz-split Mar 19, 2021
8582e4b
Merge branch 'master' into master-to-dev
sanzmauro Mar 19, 2021
c0cdc52
Merge pull request #197 from splitio/master-to-dev
ldecheverz-split Mar 19, 2021
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
6 changes: 6 additions & 0 deletions client/CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
CHANGES

4.1.4 (Mar 19, 2021)
- Updated: Internal cache structure refactor.
- Updated: Streaming revamp with several bugfixes and improved log messages.
- Added: Cache-Control header for on-demand requests to sdk-server.
- Updated: Localhost Client revamp & bugfix for missing splits.

4.1.3 (Dec 2, 2020)
- Fix Issue when closing SSE Connection
- Updated log-level for some messages
Expand Down
2 changes: 1 addition & 1 deletion client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.split.client</groupId>
<artifactId>java-client-parent</artifactId>
<version>4.1.3</version>
<version>4.1.4</version>
</parent>
<artifactId>java-client</artifactId>
<packaging>jar</packaging>
Expand Down
126 changes: 126 additions & 0 deletions client/src/main/java/io/split/cache/InMemoryCacheImp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package io.split.cache;

import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import io.split.engine.experiments.ParsedSplit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

public class InMemoryCacheImp implements SplitCache {

private static final Logger _log = LoggerFactory.getLogger(InMemoryCacheImp.class);

private final ConcurrentMap<String, ParsedSplit> _concurrentMap;
private final Multiset<String> _concurrentTrafficTypeNameSet;

private AtomicLong _changeNumber;

public InMemoryCacheImp() {
this(-1);
}

public InMemoryCacheImp(long startingChangeNumber) {
_concurrentMap = Maps.newConcurrentMap();
_changeNumber = new AtomicLong(startingChangeNumber);
_concurrentTrafficTypeNameSet = ConcurrentHashMultiset.create();
}

@Override
public void put(ParsedSplit split) {
_concurrentMap.put(split.feature(), split);

if (split.trafficTypeName() != null) {
_concurrentTrafficTypeNameSet.add(split.trafficTypeName());
}
}

@Override
public boolean remove(String name) {
ParsedSplit removed = _concurrentMap.remove(name);

if (removed != null && removed.trafficTypeName() != null) {
_concurrentTrafficTypeNameSet.remove(removed.trafficTypeName());
}

return removed != null;
}

@Override
public ParsedSplit get(String name) {
return _concurrentMap.get(name);
}

@Override
public Collection<ParsedSplit> getAll() {
return _concurrentMap.values();
}

@Override
public Collection<ParsedSplit> getMany(List<String> names) {
List<ParsedSplit> splits = new ArrayList<>();

for (String name : names) {
ParsedSplit split = _concurrentMap.get(name);

if (split != null) {
splits.add(split);
}
}

return splits;
}

@Override
public long getChangeNumber() {
return _changeNumber.get();
}

@Override
public void setChangeNumber(long changeNumber) {
if (changeNumber < _changeNumber.get()) {
_log.error("ChangeNumber for splits cache is less than previous");
}

_changeNumber.set(changeNumber);
}

@Override
public boolean trafficTypeExists(String trafficTypeName) {
// If the multiset has [{"user",2}.{"account",0}], elementSet only returns
// ["user"] (it ignores "account")
return Sets.newHashSet(_concurrentTrafficTypeNameSet.elementSet()).contains(trafficTypeName);
}

@Override
public void kill(String splitName, String defaultTreatment, long changeNumber) {
ParsedSplit parsedSplit = _concurrentMap.get(splitName);

ParsedSplit updatedSplit = new ParsedSplit(parsedSplit.feature(),
parsedSplit.seed(),
true,
defaultTreatment,
parsedSplit.parsedConditions(),
parsedSplit.trafficTypeName(),
changeNumber,
parsedSplit.trafficAllocation(),
parsedSplit.trafficAllocationSeed(),
parsedSplit.algo(),
parsedSplit.configurations());

_concurrentMap.put(splitName, updatedSplit);
}

@Override
public void clear() {
_concurrentMap.clear();
_concurrentTrafficTypeNameSet.clear();
}
}
45 changes: 45 additions & 0 deletions client/src/main/java/io/split/cache/SegmentCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.split.cache;

import java.util.List;

/**
* Memory for segments
* @author lucasecheverz
*/
public interface SegmentCache {

/**
* update segment
* @param segmentName
* @param toAdd
* @param toRemove
*/
void updateSegment(String segmentName, List<String> toAdd, List<String> toRemove) ;

/**
* evaluates if a key belongs to a segment
* @param segmentName
* @param key
* @return
*/
boolean isInSegment(String segmentName, String key);

/**
* update the changeNumber of a segment
* @param segmentName
* @param changeNumber
*/
void setChangeNumber(String segmentName, long changeNumber);

/**
* returns the changeNumber of a segment
* @param segmentName
* @return
*/
long getChangeNumber(String segmentName);

/**
* clear all segments
*/
void clear();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.split.cache;

import com.google.common.collect.Maps;
import io.split.engine.segments.SegmentImp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ConcurrentMap;

/**
* InMemoryCache Implementation
* @author lucasecheverz
*/
public class SegmentCacheInMemoryImpl implements SegmentCache {
private static final Logger _log = LoggerFactory.getLogger(SegmentCacheInMemoryImpl.class);
private static final long DEFAULT_CHANGE_NUMBER = -1l;
private final ConcurrentMap<String, SegmentImp> _segments = Maps.newConcurrentMap();

@Override
public void updateSegment(String segmentName, List<String> toAdd, List<String> toRemove) {
if(_segments.get(segmentName) == null){
_segments.put(segmentName, new SegmentImp(DEFAULT_CHANGE_NUMBER, segmentName,toAdd));
}

_segments.get(segmentName).update(toAdd,toRemove);
}

@Override
public boolean isInSegment(String segmentName, String key) {
SegmentImp segmentImp = _segments.get(segmentName);
if(segmentImp == null){
_log.error("Segment " + segmentName + "Not found.");
return false;
}
return segmentImp.contains(key);
}

@Override
public void setChangeNumber(String segmentName, long changeNumber) {
if(_segments.get(segmentName) == null){
_log.error("Segment " + segmentName + "Not found.");
return ;
}
_segments.get(segmentName).setChangeNumber(changeNumber);
}

@Override
public long getChangeNumber(String segmentName) {
SegmentImp segmentImp = _segments.get(segmentName);
if(segmentImp == null){
_log.error("Segment " + segmentName + "Not found.");
return DEFAULT_CHANGE_NUMBER;
}
return segmentImp.getChangeNumber();
}

@Override
public void clear() {
_segments.clear();
}
}
19 changes: 19 additions & 0 deletions client/src/main/java/io/split/cache/SplitCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.split.cache;

import io.split.engine.experiments.ParsedSplit;

import java.util.Collection;
import java.util.List;

public interface SplitCache {
void put(ParsedSplit split);
boolean remove(String name);
ParsedSplit get(String name);
Collection<ParsedSplit> getAll();
Collection<ParsedSplit> getMany(List<String> names);
long getChangeNumber();
void setChangeNumber(long changeNumber);
boolean trafficTypeExists(String trafficTypeName);
void kill(String splitName, String defaultTreatment, long changeNumber);
void clear();
}
66 changes: 66 additions & 0 deletions client/src/main/java/io/split/client/ApiKeyCounter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.split.client;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Multiset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApiKeyCounter {

private static final Logger _log = LoggerFactory.getLogger(ApiKeyCounter.class);
private static final Multiset<String> USED_API_KEYS = ConcurrentHashMultiset.create();

private ApiKeyCounter() {}

public static ApiKeyCounter getApiKeyCounterInstance() {
return ApyKeyCounterHolder.INSTANCE;
}

//Inner class to provide instance of class
private static class ApyKeyCounterHolder
{
private static final ApiKeyCounter INSTANCE = new ApiKeyCounter();
}

public void add(String apiKey) {
String message;
if (USED_API_KEYS.contains(apiKey)) {
message = String.format("factory instantiation: You already have %s with this API Key. " +
"We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing " +
"it throughout your application.",
USED_API_KEYS.count(apiKey) == 1 ? "1 factory" : String.format("%s factories", USED_API_KEYS.count(apiKey)));
_log.warn(message);
} else if (!USED_API_KEYS.isEmpty()) {
message = "factory instantiation: You already have an instance of the Split factory. " +
"Make sure you definitely want this additional instance. We recommend keeping only one instance of " +
"the factory at all times (Singleton pattern) and reusing it throughout your application.“";
_log.warn(message);
}
USED_API_KEYS.add(apiKey);
}

public void remove(String apiKey) {
USED_API_KEYS.remove(apiKey);
}

/**
* Just for test
* @param apiKey
* @return
*/
@VisibleForTesting
boolean isApiKeyPresent(String apiKey) {
return USED_API_KEYS.contains(apiKey);
}

/**
* Just for test
* @param apiKey
* @return
*/
@VisibleForTesting
int getCount(String apiKey) {
return USED_API_KEYS.count(apiKey);
}
}
Loading