Skip to content
Projects
Groups
Snippets
Help
Sign in / Register
Toggle navigation
U
unleash-client-php
Project overview
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
0
Merge Requests
2
CI / CD
Security & Compliance
Packages
Wiki
Snippets
Members
Collapse sidebar
Close sidebar
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
unleash-client-php
Commits
ede7119d
Commit
ede7119d
authored
1 hour ago
by
Emiliano Balbuena
Browse files
Options
Download
(feat): Strategy Algorithms and resolver
parent
ac64d7ca
goal/clean-up-unleash-client
1 merge request
!2
WIP: Clean up and strategies
Pipeline
#105679728
passed with stage
in 1 minute and 6 seconds
Changes
12
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
287 additions
and
8 deletions
+287
-8
src/Factories/StrategyAlgorithmFactory.php
0 → 100644
View file @
ede7119d
<?php
/**
* StrategyAlgorithmFactory
*
* @author edgebal
*/
namespace
Minds\UnleashClient\Factories
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Minds\UnleashClient\StrategyAlgorithms\StrategyAlgorithm
;
use
Psr\Log\LoggerInterface
;
class
StrategyAlgorithmFactory
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* StrategyAlgorithmFactory constructor.
* @param LoggerInterface|null $logger
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* Builds a new strategy algorithm instance
* @param Strategy $strategy
* @return StrategyAlgorithm|null
*/
public
function
build
(
Strategy
$strategy
)
:
?
StrategyAlgorithm
{
$className
=
sprintf
(
"
\\
Minds
\\
UnleashClient
\\
StrategyAlgorithms
\\
%sStrategyAlgorithm"
,
ucfirst
(
$strategy
->
getName
()));
if
(
!
class_exists
(
$className
))
{
$this
->
logger
->
warning
(
"
{
$className
}
does not exist"
);
return
null
;
}
$strategyAlgorithm
=
new
$className
(
$this
->
logger
);
if
(
!
(
$strategyAlgorithm
instanceof
StrategyAlgorithm
))
{
$this
->
logger
->
warning
(
sprintf
(
"%s is not an %s instance"
,
$strategyAlgorithm
,
StrategyAlgorithm
::
class
));
return
null
;
}
$this
->
logger
->
debug
(
"Created a new
{
$className
}
instance"
);
return
$strategyAlgorithm
;
}
}
This diff is collapsed.
src/StrategyAlgorithms/ApplicationHostnameStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,9 +9,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
ApplicationHostnameStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -26,6 +40,11 @@ class ApplicationHostnameStrategyAlgorithm implements StrategyAlgorithm
$hostNames
=
array_map
([
$this
,
'normalizeHostName'
],
explode
(
','
,
$hostNamesList
));
$this
->
logger
->
debug
(
static
::
class
,
[
$context
->
getHostName
(),
$hostNames
]);
return
in_array
(
strtolower
(
$context
->
getHostName
()),
$hostNames
,
true
);
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/DefaultStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,14 +9,30 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
DefaultStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
public
function
isEnabled
(
Strategy
$strategy
,
Context
$context
)
:
bool
{
$this
->
logger
->
debug
(
static
::
class
,
[
true
]);
return
true
;
}
}
This diff is collapsed.
src/StrategyAlgorithms/FlexibleRolloutStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -10,9 +10,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Helpers\NormalizedValue
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
FlexibleRolloutStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -20,7 +34,7 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm
{
$parameters
=
$strategy
->
getParameters
();
$percentage
=
$parameters
[
'rollout'
]
??
0
;
$percentage
=
intval
(
$parameters
[
'rollout'
]
??
0
)
;
$stickiness
=
$parameters
[
'stickiness'
]
??
'default'
;
$groupId
=
trim
(
$parameters
[
'groupId'
]
??
''
);
$userId
=
trim
(
$context
->
getUserId
()
??
''
);
...
...
@@ -50,6 +64,12 @@ class FlexibleRolloutStrategyAlgorithm implements StrategyAlgorithm
$stickinessValue
=
NormalizedValue
::
build
(
$stickinessId
,
$groupId
);
$this
->
logger
->
debug
(
static
::
class
,
[
$stickiness
,
$stickinessValue
,
$percentage
]);
return
$percentage
>
0
&&
$stickinessValue
<=
$percentage
;
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/GradualRolloutRandomStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,9 +9,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
GradualRolloutRandomStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -19,9 +33,14 @@ class GradualRolloutRandomStrategyAlgorithm implements StrategyAlgorithm
{
$parameters
=
$strategy
->
getParameters
();
$percentage
=
$parameters
[
'percentage'
]
??
0
;
$percentage
=
intval
(
$parameters
[
'percentage'
]
??
0
)
;
$random
=
mt_rand
(
1
,
100
);
$this
->
logger
->
debug
(
static
::
class
,
[
$random
,
$percentage
]);
return
$percentage
>
0
&&
$random
<=
$percentage
;
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/GradualRolloutSessionIdStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -10,9 +10,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Helpers\NormalizedValue
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
GradualRolloutSessionIdStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -20,7 +34,7 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm
{
$parameters
=
$strategy
->
getParameters
();
$percentage
=
$parameters
[
'percentage'
]
??
0
;
$percentage
=
intval
(
$parameters
[
'percentage'
]
??
0
)
;
$groupId
=
trim
(
$parameters
[
'groupId'
]
??
''
);
$sessionId
=
trim
(
$context
->
getSessionId
()
??
''
);
...
...
@@ -30,6 +44,11 @@ class GradualRolloutSessionIdStrategyAlgorithm implements StrategyAlgorithm
$sessionIdValue
=
NormalizedValue
::
build
(
$sessionId
,
$groupId
);
$this
->
logger
->
debug
(
static
::
class
,
[
$sessionIdValue
,
$percentage
]);
return
$percentage
>
0
&&
$sessionIdValue
<=
$percentage
;
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/GradualRolloutUserIdStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -10,9 +10,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Helpers\NormalizedValue
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
GradualRolloutUserIdStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -20,7 +34,7 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm
{
$parameters
=
$strategy
->
getParameters
();
$percentage
=
$parameters
[
'percentage'
]
??
0
;
$percentage
=
intval
(
$parameters
[
'percentage'
]
??
0
)
;
$groupId
=
trim
(
$parameters
[
'groupId'
]
??
''
);
$userId
=
trim
(
$context
->
getUserId
()
??
''
);
...
...
@@ -30,6 +44,11 @@ class GradualRolloutUserIdStrategyAlgorithm implements StrategyAlgorithm
$userIdValue
=
NormalizedValue
::
build
(
$userId
,
$groupId
);
$this
->
logger
->
debug
(
static
::
class
,
[
$userIdValue
,
$percentage
]);
return
$percentage
>
0
&&
$userIdValue
<=
$percentage
;
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/RemoteAddressStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,9 +9,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
RemoteAddressStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -26,6 +40,11 @@ class RemoteAddressStrategyAlgorithm implements StrategyAlgorithm
$ipAddresses
=
array_map
([
$this
,
'normalizeIpAddress'
],
explode
(
','
,
$ipAddressesList
));
$this
->
logger
->
debug
(
static
::
class
,
[
$context
->
getRemoteAddress
(),
$ipAddresses
]);
return
in_array
(
strtolower
(
$context
->
getRemoteAddress
()),
$ipAddresses
,
true
);
}
...
...
This diff is collapsed.
src/StrategyAlgorithms/StrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,9 +9,16 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Psr\Log\LoggerInterface
;
interface
StrategyAlgorithm
{
/**
* StrategyAlgorithm constructor.
* @param LoggerInterface $logger
*/
public
function
__construct
(
LoggerInterface
$logger
);
/**
* Resolves a strategy using the context
* @param Strategy $strategy
...
...
This diff is collapsed.
src/StrategyAlgorithms/UserWithIdStrategyAlgorithm.php
View file @
ede7119d
...
...
@@ -9,9 +9,23 @@ namespace Minds\UnleashClient\StrategyAlgorithms;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Entities\Strategy
;
use
Minds\UnleashClient\Logger
;
use
Psr\Log\LoggerInterface
;
class
UserWithIdStrategyAlgorithm
implements
StrategyAlgorithm
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/**
* @inheritDoc
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
}
/**
* @inheritDoc
*/
...
...
@@ -26,6 +40,11 @@ class UserWithIdStrategyAlgorithm implements StrategyAlgorithm
$userIds
=
array_map
([
$this
,
'normalizeUserId'
],
explode
(
','
,
$userIdsList
));
$this
->
logger
->
debug
(
static
::
class
,
[
$context
->
getUserId
(),
$userIds
]);
return
in_array
(
$context
->
getUserId
(),
$userIds
,
true
);
}
...
...
This diff is collapsed.
src/StrategyResolver.php
0 → 100644
View file @
ede7119d
<?php
/**
* StrategyResolver
*
* @author edgebal
*/
namespace
Minds\UnleashClient
;
use
Minds\UnleashClient\Entities\Context
;
use
Minds\UnleashClient\Factories\StrategyAlgorithmFactory
;
use
Minds\UnleashClient\StrategyAlgorithms\StrategyAlgorithm
;
use
Psr\Log\LoggerInterface
;
class
StrategyResolver
{
/** @var LoggerInterface|Logger */
protected
$logger
;
/** @var StrategyAlgorithmFactory */
protected
$strategyAlgorithmFactory
;
/**
* StrategyResolver constructor.
* @param LoggerInterface|null $logger
* @param StrategyAlgorithm|null $strategyAlgorithmFactory
*/
public
function
__construct
(
LoggerInterface
$logger
=
null
,
StrategyAlgorithm
$strategyAlgorithmFactory
=
null
)
{
$this
->
logger
=
$logger
?:
new
Logger
();
$this
->
strategyAlgorithmFactory
=
$strategyAlgorithmFactory
?:
new
StrategyAlgorithmFactory
(
$this
->
logger
);
}
/**
* Instantiates a new strategy algorithm based on the passed strategy and run it against
* the context
* @param array $strategies
* @param Context $context
* @return bool
*/
public
function
isEnabled
(
array
$strategies
,
Context
$context
)
:
bool
{
foreach
(
$strategies
as
$strategy
)
{
$strategyAlgorithm
=
$this
->
strategyAlgorithmFactory
->
build
(
$strategy
);
if
(
$strategyAlgorithm
->
isEnabled
(
$strategy
,
$context
))
{
return
true
;
}
}
return
false
;
}
}
This diff is collapsed.
src/Unleash.php
View file @
ede7119d
...
...
@@ -17,7 +17,7 @@ class Unleash
/** @var Config */
protected
$config
;
/** @var LoggerInterface */
/** @var Logger
|Logger
Interface */
protected
$logger
;
/** @var Client */
...
...
@@ -26,6 +26,9 @@ class Unleash
/** @var Cache\SimpleCache|CacheInterface */
protected
$cache
;
/** @var StrategyResolver */
protected
$strategyResolver
;
/** @var bool */
protected
$isClientRegistered
=
false
;
...
...
@@ -38,18 +41,21 @@ class Unleash
* @param LoggerInterface|null $logger
* @param Client|null $client
* @param CacheInterface|null $cache
* @param StrategyResolver|null $strategyResolver
*/
public
function
__construct
(
Config
$config
=
null
,
LoggerInterface
$logger
=
null
,
Client
$client
=
null
,
CacheInterface
$cache
=
null
CacheInterface
$cache
=
null
,
StrategyResolver
$strategyResolver
=
null
)
{
$this
->
config
=
$config
?:
new
Config
();
$this
->
logger
=
$logger
?:
new
Logger
();
$this
->
client
=
$client
?:
new
Client
(
$this
->
config
,
$this
->
logger
);
$this
->
cache
=
$cache
?:
new
Cache\SimpleCache
(
$this
->
logger
);
$this
->
strategyResolver
=
$strategyResolver
?:
new
StrategyResolver
(
$this
->
logger
);
}
/**
...
...
@@ -80,14 +86,19 @@ class Unleash
$this
->
fetch
();
}
/** @var Entities\Feature|null */
/** @var Entities\Feature|null
$feature
*/
$feature
=
$this
->
cache
->
get
(
$this
->
buildCacheKey
(
$featureName
),
null
);
if
(
$feature
===
null
)
{
return
$default
;
}
return
$feature
->
isEnabled
();
return
$feature
->
isEnabled
()
&&
$this
->
strategyResolver
->
isEnabled
(
$feature
->
getStrategies
(),
$this
->
context
);
}
catch
(
\Exception
$e
)
{
$this
->
logger
->
error
(
"Error checking feature flag
{
$featureName
}
"
);
$this
->
logger
->
error
(
$e
);
...
...
This diff is collapsed.
Please
register
or
sign in
to comment