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

Empty datafile passed before fetching datafile #25

Merged
merged 5 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 src/main/kotlin/com/featurevisor/sdk/DatafileReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.featurevisor.types.FeatureKey
import com.featurevisor.types.Segment
import com.featurevisor.types.SegmentKey

class DatafileReader constructor(
class DatafileReader (
datafileJson: DatafileContent,
) {

Expand Down
44 changes: 24 additions & 20 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Activation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,31 @@ import com.featurevisor.types.FeatureKey
import com.featurevisor.types.VariationValue

fun FeaturevisorInstance.activate(featureKey: FeatureKey, context: Context = emptyMap()): VariationValue? {
val evaluation = evaluateVariation(featureKey, context)
val variationValue = evaluation.variation?.value ?: evaluation.variationValue ?: return null
val finalContext = interceptContext?.invoke(context) ?: context
val captureContext = mutableMapOf<String, AttributeValue>()
val attributesForCapturing = datafileReader.getAllAttributes()
.filter { it.capture == true }
return try {
val evaluation = evaluateVariation(featureKey, context)
val variationValue = evaluation.variation?.value ?: evaluation.variationValue ?: return null
val finalContext = interceptContext?.invoke(context) ?: context
val captureContext = mutableMapOf<String, AttributeValue>()
val attributesForCapturing = datafileReader.getAllAttributes()
.filter { it.capture == true }

attributesForCapturing.forEach { attribute ->
finalContext[attribute.key]?.let {
captureContext[attribute.key] = it
}
}
attributesForCapturing.forEach { attribute ->
finalContext[attribute.key]?.let {
captureContext[attribute.key] = it
}
}

emitter.emit(
ACTIVATION,
featureKey,
variationValue,
finalContext,
captureContext,
evaluation
)
emitter.emit(
ACTIVATION,
featureKey,
variationValue,
finalContext,
captureContext,
evaluation
)

return variationValue
variationValue
}catch (e:Exception){
null
}
}
81 changes: 50 additions & 31 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Feature.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,41 @@ import com.featurevisor.types.Force
import com.featurevisor.types.Traffic

fun FeaturevisorInstance.getFeatureByKey(featureKey: String): Feature? {
return datafileReader.getFeature(featureKey)
return try {
datafileReader.getFeature(featureKey)
}catch (e:Exception){
null
}
}

fun FeaturevisorInstance.getFeature(featureKey: String): Feature?{
return datafileReader.getFeature(featureKey)
return try {
datafileReader.getFeature(featureKey)
}catch (e:Exception){
null
}
}

internal fun FeaturevisorInstance.findForceFromFeature(
feature: Feature,
context: Context,
datafileReader: DatafileReader,
): Force? {
return try {
feature.force?.firstOrNull { force ->
when {
force.conditions != null -> allConditionsAreMatched(force.conditions, context)
force.segments != null -> allGroupSegmentsAreMatched(
force.segments,
context,
datafileReader
)

return feature.force?.firstOrNull { force ->
when {
force.conditions != null -> allConditionsAreMatched(force.conditions, context)
force.segments != null -> allGroupSegmentsAreMatched(
force.segments,
context,
datafileReader
)

else -> false
else -> false
}
}
}catch (e:Exception){
null
}
}

Expand All @@ -40,27 +51,33 @@ internal fun FeaturevisorInstance.getMatchedTraffic(
context: Context,
datafileReader: DatafileReader,
): Traffic? {

return traffic.firstOrNull { trafficItem ->
allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader)
return try {
traffic.firstOrNull { trafficItem ->
allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader)
}
}catch (e:Exception){
null
}
}

internal fun FeaturevisorInstance.getMatchedAllocation(
traffic: Traffic,
bucketValue: Int,
): Allocation? {

return traffic.allocation.firstOrNull { allocation ->
with(allocation.range) {
bucketValue in this.first()..this.last()
return try {
traffic.allocation.firstOrNull { allocation ->
with(allocation.range) {
bucketValue in this.first()..this.last()
}
}
}catch (e:Exception){
null
}
}

data class MatchedTrafficAndAllocation(
val matchedTraffic: Traffic?,
val matchedAllocation: Allocation?,
val matchedTraffic: Traffic?=null,
val matchedAllocation: Allocation?=null,
)

internal fun FeaturevisorInstance.getMatchedTrafficAndAllocation(
Expand All @@ -70,16 +87,18 @@ internal fun FeaturevisorInstance.getMatchedTrafficAndAllocation(
datafileReader: DatafileReader,
logger: Logger?,
): MatchedTrafficAndAllocation {

var matchedAllocation: Allocation? = null
val matchedTraffic = traffic.firstOrNull { trafficItem ->
if (allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader)) {
matchedAllocation = getMatchedAllocation(trafficItem, bucketValue)
true
} else {
false
return try {
var matchedAllocation: Allocation? = null
val matchedTraffic = traffic.firstOrNull { trafficItem ->
if (allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader)) {
matchedAllocation = getMatchedAllocation(trafficItem, bucketValue)
true
} else {
false
}
}
MatchedTrafficAndAllocation(matchedTraffic, matchedAllocation)
}catch (e:Exception){
MatchedTrafficAndAllocation()
}

return MatchedTrafficAndAllocation(matchedTraffic, matchedAllocation)
}
14 changes: 9 additions & 5 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Fetch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ internal fun FeaturevisorInstance.fetchDatafileContent(
handleDatafileFetch: DatafileFetchHandler? = null,
completion: (Result<DatafileContent>) -> Unit,
) {
handleDatafileFetch?.let { handleFetch ->
val result = handleFetch(url)
completion(result)
} ?: run {
fetchDatafileContentFromUrl(url, completion)
try {
handleDatafileFetch?.let { handleFetch ->
val result = handleFetch(url)
completion(result)
} ?: run {
fetchDatafileContentFromUrl(url, completion)
}
}catch (e:Exception){
completion(Result.failure(FeaturevisorError.InvalidUrl(url)))
}
}

Expand Down
75 changes: 42 additions & 33 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Segments.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ internal fun FeaturevisorInstance.segmentIsMatched(
featureKey: FeatureKey,
context: Context,
): VariationValue? {
val evaluation = evaluateVariation(featureKey, context)
return try {
val evaluation = evaluateVariation(featureKey, context)
var variationValue: VariationValue? = null

if (evaluation.variationValue != null) {
return evaluation.variationValue
}
if (evaluation.variationValue != null) {
variationValue = evaluation.variationValue
}

if (evaluation.variation != null) {
return evaluation.variation.value
}
if (evaluation.variation != null) {
variationValue = evaluation.variation.value
}

return null
variationValue
} catch (e: Exception) {
null
}
}

internal fun segmentIsMatched(segment: Segment, context: Context): Boolean {
Expand All @@ -34,40 +39,44 @@ internal fun FeaturevisorInstance.allGroupSegmentsAreMatched(
context: Context,
datafileReader: DatafileReader,
): Boolean {
return when (groupSegments) {
is Plain -> {
val segmentKey = groupSegments.segment
if (segmentKey == "*") {
true
} else {
datafileReader.getSegment(segmentKey)?.let {
segmentIsMatched(it, context)
} ?: false
return try {
when (groupSegments) {
is Plain -> {
val segmentKey = groupSegments.segment
if (segmentKey == "*") {
true
} else {
datafileReader.getSegment(segmentKey)?.let {
segmentIsMatched(it, context)
} ?: false
}
}
}

is Multiple -> {
groupSegments.segments.all {
allGroupSegmentsAreMatched(it, context, datafileReader)
is Multiple -> {
groupSegments.segments.all {
allGroupSegmentsAreMatched(it, context, datafileReader)
}
}
}

is And -> {
groupSegments.segment.and.all {
allGroupSegmentsAreMatched(it, context, datafileReader)
is And -> {
groupSegments.segment.and.all {
allGroupSegmentsAreMatched(it, context, datafileReader)
}
}
}

is Or -> {
groupSegments.segment.or.any {
allGroupSegmentsAreMatched(it, context, datafileReader)
is Or -> {
groupSegments.segment.or.any {
allGroupSegmentsAreMatched(it, context, datafileReader)
}
}
}

is Not -> {
groupSegments.segment.not.all {
allGroupSegmentsAreMatched(it, context, datafileReader).not()
is Not -> {
groupSegments.segment.not.all {
allGroupSegmentsAreMatched(it, context, datafileReader).not()
}
}
}
}catch (e:Exception){
false
}
}
25 changes: 19 additions & 6 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Variable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.featurevisor.types.VariableValue.IntValue
import com.featurevisor.types.VariableValue.JsonValue
import com.featurevisor.types.VariableValue.ObjectValue
import com.featurevisor.types.VariableValue.StringValue
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
Expand All @@ -21,13 +22,17 @@ fun FeaturevisorInstance.getVariable(
variableKey: VariableKey,
context: Context = emptyMap(),
): VariableValue? {
val evaluation = evaluateVariable(
featureKey = featureKey,
variableKey = variableKey,
context = context
)
return try {
val evaluation = evaluateVariable(
featureKey = featureKey,
variableKey = variableKey,
context = context
)

return evaluation.variableValue
evaluation.variableValue
} catch (e: Exception) {
null
}
}

fun FeaturevisorInstance.getVariableBoolean(
Expand Down Expand Up @@ -97,3 +102,11 @@ inline fun <reified T : Any> FeaturevisorInstance.getVariableJSON(
}
}

@Serializable
data class CountriesWithStringValueAndSeparateDefault(
val country: Map<String, String>?,
val default: String?,
)



14 changes: 9 additions & 5 deletions src/main/kotlin/com/featurevisor/sdk/Instance+Variation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import com.featurevisor.types.FeatureKey
import com.featurevisor.types.VariationValue

internal fun FeaturevisorInstance.getVariation(featureKey: FeatureKey, context: Context): VariationValue? {
val evaluation = evaluateVariation(featureKey, context)
return when {
evaluation.variationValue != null -> evaluation.variationValue
evaluation.variation != null -> evaluation.variation.value
else -> null
return try {
val evaluation = evaluateVariation(featureKey, context)
return when {
evaluation.variationValue != null -> evaluation.variationValue
evaluation.variation != null -> evaluation.variation.value
else -> null
}
}catch (e:Exception){
null
}
}
Loading
Loading