Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
Easy Http SDK
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
4
Issues
4
List
Board
Labels
Milestones
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Back End
Easy Http SDK
Commits
0363bd45
Commit
0363bd45
authored
Aug 22, 2024
by
朱思嘉
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(application): application
parent
d2faec26
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
606 additions
and
41 deletions
+606
-41
Application.php
src/Application.php
+25
-9
ApplicationException.php
src/Exception/ApplicationException.php
+20
-1
Option.php
src/Option.php
+21
-1
ApplicationTest.php
tests/unit/ApplicationTest.php
+335
-2
OptionTest.php
tests/unit/OptionTest.php
+126
-28
OptionTestBak.php
tests/unit/OptionTestBak.php
+79
-0
No files found.
src/Application.php
View file @
0363bd45
...
...
@@ -29,6 +29,8 @@ class Application implements ClientInterface
private
const
TOKEN_CACHE_KEY
=
"Auth.%s"
;
/** @var string jwtToken */
private
$jwtToken
=
""
;
...
...
@@ -71,6 +73,10 @@ class Application implements ClientInterface
throw
new
RuntimeException
(
"请完善配置信息中的App Secret"
);
}
if
(
empty
(
$option
->
getCustomer
())){
throw
new
RuntimeException
(
"请完善配置信息中的 Customer"
);
}
$this
->
option
=
$option
;
$base_url
=
$option
->
getBaseUrl
();
...
...
@@ -81,6 +87,7 @@ class Application implements ClientInterface
if
(
$logger
)
{
$this
->
logger
=
$logger
;
$this
->
logger
->
info
(
"Application initialized with customer information: "
.
$this
->
option
->
getCustomer
());
}
$this
->
cache
=
new
FilesystemAdapter
();
...
...
@@ -163,7 +170,7 @@ class Application implements ClientInterface
$this
->
jwtToken
=
$this
->
getAccessTokenFromCache
();
}
catch
(
CacheInvalidArgumentException
$exception
)
{
// 缓存异常
throw
new
ApplicationException
(
"auth cache error "
.
$exception
->
getMessage
()
);
throw
new
ApplicationException
(
"auth cache error "
.
$exception
->
getMessage
(),
$request
,
[],
$exception
,
[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
catch
(
TransferException
$exception
)
{
// 超时异常
if
(
$this
->
logger
)
{
...
...
@@ -175,7 +182,7 @@ class Application implements ClientInterface
if
(
$this
->
logger
)
{
$this
->
logger
->
error
(
"sdk error, cause by:"
.
$exception
->
getMessage
());
}
throw
new
ApplicationException
(
$exception
->
getMessage
(),
$request
,
[],
$exception
);
throw
new
ApplicationException
(
$exception
->
getMessage
(),
$request
,
[],
$exception
,[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
}
$authMiddleware
=
$this
->
option
->
getAuthorizationMiddleware
();
...
...
@@ -203,9 +210,9 @@ class Application implements ClientInterface
$this
->
logger
->
error
(
"sdk error, bad client!"
);
}
if
(
!
(
$request
instanceof
SdkRequest
))
{
throw
new
ApplicationException
(
$exception
->
getMessage
(),
null
,
[],
$exception
);
throw
new
ApplicationException
(
$exception
->
getMessage
(),
null
,
[],
$exception
,[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
throw
new
ApplicationException
(
$exception
->
getMessage
(),
$request
,
[],
$exception
);
throw
new
ApplicationException
(
$exception
->
getMessage
(),
$request
,
[],
$exception
,[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
$this
->
lastRequestContext
[
'expend'
]
=
sprintf
(
"%dms"
,
microtime
(
true
)
*
1000
-
$start
*
1000
);
...
...
@@ -229,10 +236,10 @@ class Application implements ClientInterface
// context 是没有处理前的上下文
$context
=
$this
->
lastRequestContext
;
if
(
$context
[
'request'
]
)
{
if
(
isset
(
$context
[
'request'
])
)
{
unset
(
$context
[
'request'
]);
}
if
(
$context
[
'response'
]
)
{
if
(
isset
(
$context
[
'response'
])
)
{
unset
(
$context
[
'response'
]);
}
...
...
@@ -240,14 +247,14 @@ class Application implements ClientInterface
if
(
$this
->
logger
)
{
$this
->
logger
->
error
(
"sdk error, Upstream service fail"
,
$context
);
}
throw
new
ApplicationException
(
"SDK Upstream Failed"
,
$request
,
[]);
throw
new
ApplicationException
(
"SDK Upstream Failed"
,
$request
,
[]
,
null
,
[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
if
(
$response
->
getStatusCode
()
==
401
)
{
if
(
$this
->
logger
)
{
$this
->
logger
->
error
(
"sdk error, auth fail"
,
$context
);
}
throw
new
ApplicationException
(
"auth Failed"
,
$request
,
[]);
throw
new
ApplicationException
(
"auth Failed"
,
$request
,
[]
,
null
,
[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
try
{
...
...
@@ -268,7 +275,7 @@ class Application implements ClientInterface
if
(
$this
->
logger
)
{
$this
->
logger
->
error
(
"sdk error, bad response content."
,
$this
->
lastRequestContext
);
}
throw
new
ApplicationException
(
"Content Format error."
,
$request
,
[]);
throw
new
ApplicationException
(
"Content Format error."
,
$request
,
[]
,
null
,
[
'customer'
=>
$this
->
option
->
getCustomer
()]
);
}
$version
=
$response
->
getHeader
(
'ETag'
);
...
...
@@ -293,4 +300,13 @@ class Application implements ClientInterface
{
return
$this
->
lastRequestContext
;
}
/**
* 用于测试的方法,允许注入客户端对象
*
*/
public
function
setClient
(
Client
$client
)
:
void
{
$this
->
client
=
$client
;
}
}
src/Exception/ApplicationException.php
View file @
0363bd45
...
...
@@ -11,6 +11,12 @@ class ApplicationException extends ConnectException implements SdkExceptionInter
{
use
QueryPath
;
/**
* 额外信息
* @var array<string, mixed>
*/
private
array
$additionalData
=
[];
/**
* 应用异常
*
...
...
@@ -18,15 +24,28 @@ class ApplicationException extends ConnectException implements SdkExceptionInter
* @param SdkRequest|null $request
* @param array<string, mixed> $handlerContext
* @param Throwable|null $previous
* @param array<string, mixed> $additionalData
*/
public
function
__construct
(
string
$message
,
SdkRequest
$request
=
null
,
array
$handlerContext
=
[],
?
Throwable
$previous
=
null
?
Throwable
$previous
=
null
,
array
$additionalData
=
[]
)
{
$this
->
endpoint
=
is_null
(
$request
)
?
""
:
$request
->
getEndpoint
();
$this
->
action
=
is_null
(
$request
)
?
""
:
$request
->
getAction
();
$this
->
additionalData
=
$additionalData
;
parent
::
__construct
(
$message
,
$request
,
$previous
,
$handlerContext
);
}
/**
* 获取额外的数据
*
* @return array<string, mixed>
*/
public
function
getAdditionalData
()
:
array
{
return
$this
->
additionalData
;
}
}
src/Option.php
View file @
0363bd45
...
...
@@ -29,6 +29,8 @@ abstract class Option
/** @var string App Key 应用标志 */
private
$appId
;
/** @var string App Secret 应用密钥 */
private
$customer
;
/** @var string SDK 调用者信息 */
private
$appSecret
;
/** @var string SDK 的 Stage 环境 */
private
$stage
=
"development"
;
...
...
@@ -77,13 +79,23 @@ abstract class Option
*/
public
function
setStage
(
string
$stage
)
:
self
{
if
(
empty
(
static
::
ENDPOINT_HOSTS
[
$stage
]))
{
if
(
empty
(
static
::
ENDPOINT_HOSTS
[
$stage
]))
{
throw
new
InvalidArgumentException
(
"set an undefine stage"
);
}
$this
->
stage
=
$stage
;
return
$this
;
}
/**
* @param string $caller
* @return Option
*/
public
function
setCustomer
(
string
$customer
)
:
self
{
$this
->
customer
=
$customer
;
return
$this
;
}
/**
* @param float $timeOut
* @return Option
...
...
@@ -112,6 +124,14 @@ abstract class Option
return
$this
->
appSecret
;
}
/**
* @return string
*/
public
function
getCustomer
()
:
string
{
return
$this
->
customer
;
}
/**
* @return string
*/
...
...
tests/unit/ApplicationTest.php
View file @
0363bd45
This diff is collapsed.
Click to expand it.
tests/unit/OptionTest.php
View file @
0363bd45
<?php
declare
(
strict_types
=
1
);
use
Jiwei\EasyHttpSdk\Option
;
use
Jiwei\EasyHttpSdk\Middleware\Auth\JwtMiddleware
;
use
Jiwei\EasyHttpSdk\Policy\DefaultErrorHandlingPolicy
;
use
Jiwei\EasyHttpSdk\Policy\HandlingPolicyInterface
;
use
PHPUnit\Framework\TestCase
;
final
class
OptionTest
extends
TestCase
class
OptionTest
extends
TestCase
{
private
Option
$option
;
protected
mixed
$option
=
null
;
/**
* 测试Option实现实例的初始化(以匿名函数形式)
*
* @return void
*/
public
function
setUp
()
:
void
{
parent
::
setUp
();
// TODO: Change the autogenerated stub
$this
->
option
=
new
class
()
extends
Option
{
/** @var string API鉴权地址 */
private
const
AUTH_API_ROUTE
=
"/api/access/token"
;
...
...
@@ -39,41 +39,139 @@ final class OptionTest extends TestCase
};
}
/**
*
* valid AppId
*
*/
public
function
testSetAppId
()
:
void
{
$appId
=
'test_app_id'
;
$result
=
$this
->
option
->
setAppId
(
$appId
);
$this
->
assertSame
(
$appId
,
$this
->
option
->
getAppId
());
$this
->
assertInstanceOf
(
Option
::
class
,
$result
);
}
/**
*
* valid AppSecret
*
*/
public
function
testSetAppSecret
()
:
void
{
$appSecret
=
'test_app_secret'
;
$result
=
$this
->
option
->
setAppSecret
(
$appSecret
);
$this
->
assertSame
(
$appSecret
,
$this
->
option
->
getAppSecret
());
$this
->
assertInstanceOf
(
Option
::
class
,
$result
);
}
/**
*
* valid Stage
*
*/
public
function
testSetStageWithValidStage
()
:
void
{
$stage
=
'development'
;
$result
=
$this
->
option
->
setStage
(
$stage
);
$this
->
assertSame
(
$stage
,
$this
->
option
->
getStage
());
$this
->
assertInstanceOf
(
Option
::
class
,
$result
);
}
/**
*
* invalid Stage
*
*/
public
function
testSetStageWithInvalidStage
()
:
void
{
$this
->
expectException
(
\InvalidArgumentException
::
class
);
$invalidStage
=
'invalid_stage'
;
$this
->
option
->
setStage
(
$invalidStage
);
}
/**
* 测试
*
* @return void
* Error handling policy validation
*
*/
public
function
test
OptionDefaultDebug
()
public
function
test
HandlingPolicy
()
:
void
{
$checkDebug
=
$this
->
option
->
isDebug
();
$this
->
assertEquals
(
$checkDebug
,
false
,
"默认的 debug 级别应该是 false "
);
$policy
=
$this
->
option
->
handlingPolicy
();
$this
->
assertInstanceOf
(
HandlingPolicyInterface
::
class
,
$policy
);
$this
->
assertInstanceOf
(
DefaultErrorHandlingPolicy
::
class
,
$policy
);
}
/**
* Undocumented function
*
* @return void
* Verify the authentication time
*
*/
public
function
test
OptionSetUndefineStage
()
public
function
test
GetAuthExpires
()
:
void
{
$defaultStage
=
$this
->
option
->
getStage
();
$this
->
assertEquals
(
$defaultStage
,
"development"
,
"默认的 stage 应该是 development "
);
$this
->
expectException
(
InvalidArgumentException
::
class
);
$this
->
option
->
setStage
(
"WoooHaa"
);
$this
->
assertSame
(
2400
,
$this
->
option
->
getAuthExpires
());
}
/**
* Undocumented function
*
* @return void
* Verify the timeout time
*
*/
public
function
testGetTimeOut
()
:
void
{
$this
->
assertSame
(
3.0
,
$this
->
option
->
getTimeOut
());
}
/**
*
* Verify the url time
*
*/
public
function
testGetBaseUrlWithDifferentStages
()
:
void
{
$this
->
assertSame
(
'127.0.0.1'
,
$this
->
option
->
setStage
(
'local'
)
->
getBaseUrl
());
$this
->
assertSame
(
'dev.test.com'
,
$this
->
option
->
setStage
(
'development'
)
->
getBaseUrl
());
$this
->
assertSame
(
'pro.test.com'
,
$this
->
option
->
setStage
(
'production'
)
->
getBaseUrl
());
}
/**
*
* Verify Debug
*
*/
public
function
testIsDebug
()
:
void
{
$this
->
assertFalse
(
$this
->
option
->
setDebug
(
false
)
->
isDebug
());
$this
->
assertTrue
(
$this
->
option
->
setDebug
(
true
)
->
isDebug
());
}
/**
*
* Verify Customer
*
*/
public
function
testGetCustomerAndSetCustomer
()
:
void
{
$this
->
assertSame
(
'test_customer'
,
$this
->
option
->
setCustomer
(
'test_customer'
)
->
getCustomer
());
}
/**
*
* Verify Middleware
*
*/
public
function
test
OptionBaseUrl
()
public
function
test
GetAuthorizationMiddlewareWithoutAuthMiddleware
()
:
void
{
$defaultUrl
=
$this
->
option
->
getBaseUrl
();
$this
->
assertEquals
(
$defaultUrl
,
"dev.test.com"
,
"默认的 stage 应该是 development,所以默认的 url 是 devtest"
);
$this
->
option
->
setStage
(
"production"
);
$proUrl
=
$this
->
option
->
getBaseUrl
();
$this
->
assertEquals
(
$proUrl
,
"pro.test.com"
,
"设置 Pro stage 应该可以正常显示"
);
$this
->
assertSame
(
JwtMiddleware
::
class
,
$this
->
option
->
getAuthorizationMiddleware
());
}
}
tests/unit/OptionTestBak.php
0 → 100644
View file @
0363bd45
<?php
use
Jiwei\EasyHttpSdk\Option
;
use
PHPUnit\Framework\TestCase
;
final
class
OptionTest
extends
TestCase
{
protected
mixed
$option
=
null
;
/**
* 测试Option实现实例的初始化(以匿名函数形式)
*
* @return void
*/
public
function
setUp
()
:
void
{
$this
->
option
=
new
class
()
extends
Option
{
/** @var string API鉴权地址 */
private
const
AUTH_API_ROUTE
=
"/api/access/token"
;
/** @var int API鉴权过期时间 */
const
AUTH_CACHE_EXPIRES_AT
=
2400
;
/** @var array<string, string> API HOST */
const
ENDPOINT_HOSTS
=
[
"local"
=>
"127.0.0.1"
,
"development"
=>
"dev.test.com"
,
"production"
=>
"pro.test.com"
,
];
public
function
authorization
()
:
Closure
{
return
function
()
{
echo
sprintf
(
"根据Auth API[%s]获取了TOKEN"
,
self
::
AUTH_API_ROUTE
);
return
"i am a token"
;
};
}
};
}
/**
* 测试
*
* @return void
*/
public
function
testOptionDefaultDebug
()
{
$checkDebug
=
$this
->
option
->
isDebug
();
$this
->
assertEquals
(
$checkDebug
,
false
,
"默认的 debug 级别应该是 false "
);
}
/**
* Undocumented function
*
* @return void
*/
public
function
testOptionSetUndefineStage
()
{
$defaultStage
=
$this
->
option
->
getStage
();
$this
->
assertEquals
(
$defaultStage
,
"development"
,
"默认的 stage 应该是 development "
);
$this
->
expectException
(
InvalidArgumentException
::
class
);
$this
->
option
->
setStage
(
"WoooHaa"
);
}
/**
* Undocumented function
*
* @return void
*/
public
function
testOptionBaseUrl
()
{
$defaultUrl
=
$this
->
option
->
getBaseUrl
();
$this
->
assertEquals
(
$defaultUrl
,
"dev.test.com"
,
"默认的 stage 应该是 development,所以默认的 url 是 devtest"
);
$this
->
option
->
setStage
(
"production"
);
$proUrl
=
$this
->
option
->
getBaseUrl
();
$this
->
assertEquals
(
$proUrl
,
"pro.test.com"
,
"设置 Pro stage 应该可以正常显示"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment