Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦境迷离
Scala Macro Tools
提交
8e4da614
S
Scala Macro Tools
项目概览
梦境迷离
/
Scala Macro Tools
上一次同步 大约 1 年
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Scala Macro Tools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
8e4da614
编写于
12月 07, 2021
作者:
梦境迷离
提交者:
GitHub
12月 07, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
`ProcessorCreator` Macro (#125)
use ProcessorCreator, remove Processor
上级
90795f24
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
458 addition
and
57 deletion
+458
-57
build.sbt
build.sbt
+2
-2
src/main/scala/io/github/dreamylost/ProcessorCreator.scala
src/main/scala/io/github/dreamylost/ProcessorCreator.scala
+73
-0
src/main/scala/io/github/dreamylost/macros/Creator.scala
src/main/scala/io/github/dreamylost/macros/Creator.scala
+0
-1
src/main/scala/io/github/dreamylost/macros/MacroCache.scala
src/main/scala/io/github/dreamylost/macros/MacroCache.scala
+0
-1
src/main/scala/io/github/dreamylost/macros/ProcessorCreatorMacro.scala
...a/io/github/dreamylost/macros/ProcessorCreatorMacro.scala
+205
-0
src/main/scala/io/github/dreamylost/sofa/Processable.scala
src/main/scala/io/github/dreamylost/sofa/Processable.scala
+0
-52
src/test/proto/schema.proto
src/test/proto/schema.proto
+1
-1
src/test/scala/io/github/dreamylost/ProcessorCreatorTest.scala
...est/scala/io/github/dreamylost/ProcessorCreatorTest.scala
+177
-0
未找到文件。
build.sbt
浏览文件 @
8e4da614
...
...
@@ -19,14 +19,14 @@ lazy val root = (project in file("."))
libraryDependencies
++=
Seq
(
"org.scala-lang"
%
"scala-compiler"
%
scalaVersion
.
value
,
"org.scala-lang"
%
"scala-reflect"
%
scalaVersion
.
value
,
"com.alipay.sofa"
%
"jraft-core"
%
"1.3.9"
,
"com.typesafe.scala-logging"
%%
"scala-logging"
%
"3.9.4"
,
"org.apache.logging.log4j"
%
"log4j-api"
%
"2.14.1"
%
Test
,
"org.apache.logging.log4j"
%
"log4j-core"
%
"2.14.1"
%
Test
,
"org.apache.logging.log4j"
%
"log4j-slf4j-impl"
%
"2.14.1"
%
Test
,
"com.typesafe.play"
%%
"play-json"
%
"2.7.4"
%
Test
,
"org.scalatest"
%%
"scalatest"
%
"3.2.10"
%
Test
,
"com.fasterxml.jackson.module"
%%
"jackson-module-scala"
%
"2.13.0"
%
Test
"com.fasterxml.jackson.module"
%%
"jackson-module-scala"
%
"2.13.0"
%
Test
,
"com.alipay.sofa"
%
"jraft-core"
%
"1.3.9"
%
Test
),
Compile
/
scalacOptions
++=
{
CrossVersion
.
partialVersion
(
scalaVersion
.
value
)
match
{
case
Some
((
2
,
n
))
if
n
<=
12
=>
Nil
...
...
src/main/scala/io/github/dreamylost/
sofa/CustomRpcProcess
or.scala
→
src/main/scala/io/github/dreamylost/
ProcessorCreat
or.scala
浏览文件 @
8e4da614
...
...
@@ -19,43 +19,55 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
io.github.dreamylost
.sofa
package
io.github.dreamylost
import
com.alipay.sofa.jraft.rpc.
{
RpcContext
,
RpcRequestClosure
,
RpcRequestProcessor
}
import
com.google.protobuf.Message
import
com.typesafe.scalalogging.LazyLogging
import
io.github.dreamylost.macros.ProcessorCreatorMacro
import
java.util.concurrent.Executor
import
scala.reflect.ClassTag
/**
*
Common processor
*
The macro util to generate processor for alipay sofa jraft rpc.
*
* @param executor The executor used to execute the specified sofa RPC request
* @param defaultResp Default message instance for sofa
* @tparam Req The Request proto message for sofa
* @author 梦境迷离
* @version 1.0,2021/12/
3
* @version 1.0,2021/12/
6
*/
abstract
class
CustomRpcProcessor
[
Req
<:
Message
](
executor
:
Executor
,
override
val
defaultResp
:
Message
)(
implicit
reqClassTag
:
ClassTag
[
Req
])
extends
RpcRequestProcessor
[
Req
](
executor
,
defaultResp
)
with
LazyLogging
{
object
ProcessorCreator
{
override
def
handleRequest
(
rpcCtx
:
RpcContext
,
request
:
Req
)
{
try
{
val
msg
=
processRequest
(
request
,
new
RpcRequestClosure
(
rpcCtx
,
this
.
defaultResp
))
if
(
msg
!=
null
)
{
rpcCtx
.
sendResponse
(
msg
)
}
}
catch
{
case
e
:
Exception
=>
logger
.
error
(
s
"handleRequest $request failed"
,
e
)
rpcCtx
.
sendResponse
(
processError
(
rpcCtx
,
e
))
}
}
/**
*
* @param service Instance of the [[Service]]
* @param defaultResp Default instance of the Response Message
* @param executor Instance of the Executor
* @param processRequest Function to handle request
* @param processException Function to handle exception
* @tparam RRC RpcRequestClosure
* @tparam RRP RpcRequestProcessor
* @tparam RC RpcContext
* @tparam Req Request Message of the protobuf
* @tparam Resp Response Message of the protobuf
* @tparam Service Should be custom class/interface/trait which handle the business logic of Processors
* @tparam E Should be subclass of the Executor
* @return [[ RRP ]] Instance of the RpcRequestProcessor subclass
*/
def
apply
[
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
,
Service
,
E
<:
Executor
]
(
defaultResp
:
Resp
,
processRequest
:
(
Service
,
RRC
,
Req
)
⇒
Resp
,
processException
:
(
Service
,
RC
,
Exception
)
⇒
Resp
)(
implicit
service
:
Service
,
executor
:
E
)
:
RRP
[
Req
]
=
macro
ProcessorCreatorMacro
.
SimpleImpl
[
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
,
Service
,
E
]
def
processError
(
rpcCtx
:
RpcContext
,
exception
:
Exception
)
:
Message
def
apply
[
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
,
Service
]
(
processRequest
:
(
Service
,
RRC
,
Req
)
⇒
Resp
,
processException
:
(
Service
,
RC
,
Exception
)
⇒
Resp
)(
implicit
service
:
Service
)
:
RRP
[
Req
]
=
macro
ProcessorCreatorMacro
.
WithoutExecutorAndDefaultResp
[
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
,
Service
]
override
def
interest
()
:
String
=
{
reqClassTag
.
runtimeClass
.
getName
}
/**
* Having two identical type parameters will cause the compiler to recognize error and change the order of generics to avoid.
*/
def
apply
[
Service
,
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
]
(
processRequest
:
(
Service
,
RRC
,
Req
)
⇒
Resp
,
processException
:
(
Service
,
RC
,
Exception
)
⇒
Resp
)
:
RRP
[
Req
]
=
macro
ProcessorCreatorMacro
.
OnlyWithFunctionalParameters
[
Service
,
RRC
,
RRP
[
_
<:
Req
]
,
RC
,
Req
,
Resp
]
}
src/main/scala/io/github/dreamylost/macros/Creator.scala
浏览文件 @
8e4da614
...
...
@@ -22,7 +22,6 @@
package
io.github.dreamylost.macros
import
scala.reflect.runtime.currentMirror
import
scala.reflect.runtime.universe.typeTag
import
scala.reflect.runtime.universe._
/**
...
...
src/main/scala/io/github/dreamylost/macros/MacroCache.scala
浏览文件 @
8e4da614
...
...
@@ -20,7 +20,6 @@
*/
package
io.github.dreamylost.macros
import
scala.collection.mutable
object
MacroCache
{
...
...
src/main/scala/io/github/dreamylost/
sofa/Processable
Macro.scala
→
src/main/scala/io/github/dreamylost/
macros/ProcessorCreator
Macro.scala
浏览文件 @
8e4da614
...
...
@@ -19,128 +19,160 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
io.github.dreamylost.sofa
import
com.alipay.sofa.jraft.rpc.
{
RpcContext
,
RpcRequestClosure
}
import
com.google.protobuf.Message
import
io.github.dreamylost.macros.MacroCache
package
io.github.dreamylost.macros
import
scala.reflect.macros.blackbox
import
java.time.ZonedDateTime
import
java.time.format.DateTimeFormatter
import
scala.reflect.macros.blackbox
/**
* Processable macro
*
* @author 梦境迷离
* @since 2021/12/4
* @version 1.0
* @version 1.0,2021/12/6
*/
object
Process
able
Macro
{
object
Process
orCreator
Macro
{
private
val
classNamePrefix
:
String
=
"AnonProcessor$"
def
processorWithDefaultRespServiceImpl
[
Req
<:
Message:
c.WeakTypeTag
,
Resp
<:
Message:
c.WeakTypeTag
,
Service
:
c.WeakTypeTag
]
def
SimpleImpl
[
RRC:
c.WeakTypeTag
,
RRP:
c.WeakTypeTag
,
RC:
c.WeakTypeTag
,
Req:
c.WeakTypeTag
,
Resp:
c.WeakTypeTag
,
Service:
c.WeakTypeTag
,
E
:
c.WeakTypeTag
]
(
c
:
blackbox.Context
)
(
processRequest
:
c.Expr
[(
Service
,
RpcRequestClosure
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RpcContext
,
Exception
)
⇒
Req
]
)
:
c.Expr
[
CustomRpcProcessor
[
Req
]]
=
{
defaultResp
:
c.Expr
[
Req
],
processRequest
:
c.Expr
[(
Service
,
RRC
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RC
,
Exception
)
⇒
Req
]
)(
service
:
c.Expr
[
Service
],
executor
:
c.Expr
[
E
])
:
c.Expr
[
RRP
]
=
{
// parameters in order, parameter names differ will compile error
import
c.universe._
val
serviceType
=
weakTypeOf
[
Service
]
if
(
serviceType
.
typeSymbol
.
isAbstract
||
!
serviceType
.
typeSymbol
.
isClass
)
{
c
.
abort
(
c
.
enclosingPosition
,
"Not support for abstract classes"
)
}
if
(
serviceType
.
typeSymbol
.
isModuleClass
)
{
c
.
abort
(
c
.
enclosingPosition
,
"Not support for module classes"
)
}
val
className
=
TypeName
(
classNamePrefix
+
MacroCache
.
getIdentityId
)
val
reqProtoType
=
weakTypeOf
[
Req
]
val
respProtoType
=
weakTypeOf
[
Resp
].
companion
//getDefaultInstance is static method, it's in companion
val
rpcRequestClosureType
=
weakTypeOf
[
RRC
]
val
rpcContextType
=
weakTypeOf
[
RC
]
val
respProtoType
=
weakTypeOf
[
Resp
]
val
processor
=
q
"""
class $className(private val service: $serviceType, executor: java.util.concurrent.Executor = null)
extends io.github.dreamylost.sofa.CustomRpcProcessor[$reqProtoType](executor, $respProtoType.getDefaultInstance) {
extends com.alipay.sofa.jraft.rpc.RpcRequestProcessor[$reqProtoType](executor, $defaultResp) with com.typesafe.scalalogging.LazyLogging {
override def handleRequest(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, request: $reqProtoType) {
try {
val msg = processRequest(request, new com.alipay.sofa.jraft.rpc.RpcRequestClosure(rpcCtx, this.defaultResp))
if (msg != null) {
rpcCtx.sendResponse(msg)
}
} catch {
case e: Exception =>
logger.error("handleRequest" + request + "failed", e)
rpcCtx.sendResponse(processError(rpcCtx, e))
}
}
override def interest(): String = classOf[$reqProtoType].getName
override def processRequest(request: $reqProtoType, done: com.alipay.sofa.jraft.rpc.RpcRequestClosure): com.google.protobuf.Messag
e = {
$processRequest(service, done, request)
}
def processRequest(request: $reqProtoType, done: $rpcRequestClosureType): $respProtoTyp
e = {
$processRequest(service, done, request)
}
override def processError(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, exception: Exception): com.google.protobuf.Messag
e = {
$processException(service, rpcCtx, exception)
}
def processError(rpcCtx: $rpcContextType, exception: Exception): $respProtoTyp
e = {
$processException(service, rpcCtx, exception)
}
}
val service = new io.github.dreamylost.macros.Creator[$serviceType].createInstance(null)(0)
new $className(service, null)
new $className($service, $executor)
"""
printTree
[
R
eq
](
c
)(
processor
)
printTree
[
R
RP
](
c
)(
processor
)
}
def
processorWithDefaultRespImpl
[
Service:
c.WeakTypeTag
,
Req
<:
Message:
c.WeakTypeTag
,
Resp
<:
Message:
c.WeakTypeTag
]
(
c
:
blackbox.Context
)
(
service
:
c.Expr
[
Service
])
(
processRequest
:
c.Expr
[(
Service
,
RpcRequestClosure
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RpcContext
,
Exception
)
⇒
Req
]
)
:
c.Expr
[
CustomRpcProcessor
[
Req
]]
=
{
def
WithoutExecutorAndDefaultResp
[
RRC:
c.WeakTypeTag
,
RRP:
c.WeakTypeTag
,
RC:
c.WeakTypeTag
,
Req:
c.WeakTypeTag
,
Resp:
c.WeakTypeTag
,
Service:
c.WeakTypeTag
]
(
c
:
blackbox.Context
)(
processRequest
:
c.Expr
[(
Service
,
RRC
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RC
,
Exception
)
⇒
Req
]
)(
service
:
c.Expr
[
Service
])
:
c.Expr
[
RRP
]
=
{
import
c.universe._
val
className
=
TypeName
(
classNamePrefix
+
MacroCache
.
getIdentityId
)
checkTree
[
RRC
,
RRP
,
RC
,
Service
](
c
)
val
serviceType
=
weakTypeOf
[
Service
]
val
className
=
TypeName
(
classNamePrefix
+
MacroCache
.
getIdentityId
)
val
reqProtoType
=
weakTypeOf
[
Req
]
val
respProtoType
=
weakTypeOf
[
Resp
].
companion
//getDefaultInstance is static method, it's in companion
val
rpcRequestClosureType
=
weakTypeOf
[
RRC
]
val
rpcContextType
=
weakTypeOf
[
RC
]
val
respProtoType
=
weakTypeOf
[
Resp
]
val
respProtoCompanionType
=
weakTypeOf
[
Resp
].
companion
//getDefaultInstance is static method, it's in companion
val
processor
=
q
"""
class $className(private val service: $serviceType, executor: java.util.concurrent.Executor = null)
extends io.github.dreamylost.sofa.CustomRpcProcessor[$reqProtoType](executor, $respProtoType.getDefaultInstance) {
extends com.alipay.sofa.jraft.rpc.RpcRequestProcessor[$reqProtoType](executor, $respProtoCompanionType.getDefaultInstance)
with com.typesafe.scalalogging.LazyLogging {
override def handleRequest(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, request: $reqProtoType) {
try {
val msg = processRequest(request, new com.alipay.sofa.jraft.rpc.RpcRequestClosure(rpcCtx, this.defaultResp))
if (msg != null) {
rpcCtx.sendResponse(msg)
}
} catch {
case e: Exception =>
logger.error("handleRequest" + request + "failed", e)
rpcCtx.sendResponse(processError(rpcCtx, e))
}
}
override def interest(): String = classOf[$reqProtoType].getName
override def processRequest(request: $reqProtoType, done: com.alipay.sofa.jraft.rpc.RpcRequestClosure): com.google.protobuf.Messag
e = {
$processRequest(service, done, request)
}
def processRequest(request: $reqProtoType, done: $rpcRequestClosureType): $respProtoTyp
e = {
$processRequest(service, done, request)
}
override def processError(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, exception: Exception): com.google.protobuf.Messag
e = {
$processException(service, rpcCtx, exception)
}
def processError(rpcCtx: $rpcContextType, exception: Exception): $respProtoTyp
e = {
$processException(service, rpcCtx, exception)
}
}
new $className($service
, null
)
new $className($service)
"""
printTree
[
R
eq
](
c
)(
processor
)
printTree
[
R
RP
](
c
)(
processor
)
}
def
processorImpl
[
Req
<:
Message:
c.WeakTypeTag
,
Service:
c.WeakTypeTag
,
Executor:
c.WeakTypeTag
]
(
c
:
blackbox.Context
)
(
service
:
c.Expr
[
Service
],
defaultResp
:
c.Expr
[
Req
],
executor
:
c.Expr
[
Executor
]
)
(
processRequest
:
c.Expr
[(
Service
,
RpcRequestClosure
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RpcContext
,
Exception
)
⇒
Req
]
)
:
c.Expr
[
CustomRpcProcessor
[
Req
]]
=
{
def
OnlyWithFunctionalParameters
[
Service:
c.WeakTypeTag
,
RRC:
c.WeakTypeTag
,
RRP:
c.WeakTypeTag
,
RC:
c.WeakTypeTag
,
Req:
c.WeakTypeTag
,
Resp:
c.WeakTypeTag
]
(
c
:
blackbox.Context
)(
processRequest
:
c.Expr
[(
Service
,
RRC
,
Req
)
⇒
Req
],
processException
:
c.Expr
[(
Service
,
RC
,
Exception
)
⇒
Req
]
)
:
c.Expr
[
RRP
]
=
{
import
c.universe._
val
className
=
TypeName
(
classNamePrefix
+
MacroCache
.
getIdentityId
)
checkTree
[
RRC
,
RRP
,
RC
,
Service
](
c
)
val
serviceType
=
weakTypeOf
[
Service
]
val
requestProtoType
=
weakTypeOf
[
Req
]
val
className
=
TypeName
(
classNamePrefix
+
MacroCache
.
getIdentityId
)
val
reqProtoType
=
weakTypeOf
[
Req
]
val
rpcRequestClosureType
=
weakTypeOf
[
RRC
]
val
rpcContextType
=
weakTypeOf
[
RC
]
val
respProtoType
=
weakTypeOf
[
Resp
]
val
respProtoCompanionType
=
weakTypeOf
[
Resp
].
companion
//getDefaultInstance is static method, it's in companion
val
processor
=
q
"""
class $className(private val service: $serviceType, executor: java.util.concurrent.Executor = null)
extends io.github.dreamylost.sofa.CustomRpcProcessor[$requestProtoType](executor, $defaultResp) {
extends com.alipay.sofa.jraft.rpc.RpcRequestProcessor[$reqProtoType](executor, $respProtoCompanionType.getDefaultInstance)
with com.typesafe.scalalogging.LazyLogging {
override def handleRequest(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, request: $reqProtoType) {
try {
val msg = processRequest(request, new com.alipay.sofa.jraft.rpc.RpcRequestClosure(rpcCtx, this.defaultResp))
if (msg != null) {
rpcCtx.sendResponse(msg)
}
} catch {
case e: Exception =>
logger.error("handleRequest" + request + "failed", e)
rpcCtx.sendResponse(processError(rpcCtx, e))
}
}
override def interest(): String = classOf[$reqProtoType].getName
override def processRequest(request: $requestProtoType, done: com.alipay.sofa.jraft.rpc.RpcRequestClosure): com.google.protobuf.Messag
e = {
$processRequest(service, done, request)
}
def processRequest(request: $reqProtoType, done: $rpcRequestClosureType): $respProtoTyp
e = {
$processRequest(service, done, request)
}
override def processError(rpcCtx: com.alipay.sofa.jraft.rpc.RpcContext, exception: Exception): com.google.protobuf.Messag
e = {
$processException(service, rpcCtx, exception)
}
def processError(rpcCtx: $rpcContextType, exception: Exception): $respProtoTyp
e = {
$processException(service, rpcCtx, exception)
}
}
new $className($service, $executor)
val service = new io.github.dreamylost.macros.Creator[$serviceType].createInstance(null)(0)
new $className(service)
"""
printTree
[
R
eq
](
c
)(
processor
)
printTree
[
R
RP
](
c
)(
processor
)
}
private
def
printTree
[
R
eq
<:
Message
](
c
:
blackbox.Context
)(
processor
:
c.Tree
)
:
c.Expr
[
CustomRpcProcessor
[
Req
]
]
=
{
val
ret
=
c
.
Expr
[
CustomRpcProcessor
[
Req
]
](
processor
)
private
def
printTree
[
R
RP
](
c
:
blackbox.Context
)(
processor
:
c.Tree
)
:
c.Expr
[
RRP
]
=
{
val
ret
=
c
.
Expr
[
RRP
](
processor
)
c
.
info
(
c
.
enclosingPosition
,
s
"\n###### Time: ${
...
...
@@ -151,4 +183,23 @@ object ProcessableMacro {
)
ret
}
private
def
checkTree
[
RRC:
c.WeakTypeTag
,
RRP:
c.WeakTypeTag
,
RC:
c.WeakTypeTag
,
Service:
c.WeakTypeTag
](
c
:
blackbox.Context
)
:
Unit
=
{
import
c.universe._
val
serviceType
=
weakTypeOf
[
Service
]
if
(
serviceType
.
typeSymbol
.
isAbstract
||
!
serviceType
.
typeSymbol
.
isClass
)
{
c
.
abort
(
c
.
enclosingPosition
,
"Not support for abstract classes"
)
}
if
(
serviceType
.
typeSymbol
.
isModuleClass
)
{
c
.
abort
(
c
.
enclosingPosition
,
"Not support for module classes"
)
}
val
rpcRequestClosureType
=
weakTypeOf
[
RRC
]
if
(!
rpcRequestClosureType
.
resultType
.
toString
.
equals
(
"com.alipay.sofa.jraft.rpc.RpcRequestClosure"
))
{
c
.
abort
(
c
.
enclosingPosition
,
s
"`RRC` only support for `com.alipay.sofa.jraft.rpc.RpcRequestClosure`, not `${rpcRequestClosureType.resultType.toString}`"
)
}
val
rpcContextType
=
weakTypeOf
[
RC
]
if
(!
rpcContextType
.
resultType
.
toString
.
equals
(
"com.alipay.sofa.jraft.rpc.RpcContext"
))
{
c
.
abort
(
c
.
enclosingPosition
,
s
"`RRC` only support for `com.alipay.sofa.jraft.rpc.RpcContext`, not `${rpcContextType.resultType.toString}`"
)
}
}
}
src/main/scala/io/github/dreamylost/sofa/Processable.scala
已删除
100644 → 0
浏览文件 @
90795f24
/*
* Copyright (c) 2021 jxnu-liguobin && contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
io.github.dreamylost.sofa
import
com.alipay.sofa.jraft.rpc.
{
RpcContext
,
RpcRequestClosure
}
import
com.google.protobuf.Message
/**
* The Processable util to generate processor for alipay sofa jraft rpc.
*
* @author 梦境迷离
* @version 1.0,2021/12/3
*/
object
Processable
{
def
apply
[
Req
<:
Message
,
Service
,
Executor
<:
java.util.concurrent.Executor
]
(
service
:
Service
,
defaultResp
:
Message
,
executor
:
Executor
)
(
processRequest
:
(
Service
,
RpcRequestClosure
,
Req
)
⇒
Message
,
processException
:
(
Service
,
RpcContext
,
Exception
)
⇒
Message
)
:
CustomRpcProcessor
[
Req
]
=
macro
ProcessableMacro
.
processorImpl
[
Req
,
Service
,
Executor
]
def
apply
[
Service
,
Req
<:
Message
,
Resp
<:
Message
](
service
:
Service
)
(
processRequest
:
(
Service
,
RpcRequestClosure
,
Req
)
⇒
Message
,
processException
:
(
Service
,
RpcContext
,
Exception
)
⇒
Message
)
:
CustomRpcProcessor
[
Req
]
=
macro
ProcessableMacro
.
processorWithDefaultRespImpl
[
Service
,
Req
,
Resp
]
def
apply
[
Req
<:
Message
,
Resp
<:
Message
,
Service
]
(
processRequest
:
(
Service
,
RpcRequestClosure
,
Req
)
⇒
Message
,
processException
:
(
Service
,
RpcContext
,
Exception
)
⇒
Message
)
:
CustomRpcProcessor
[
Req
]
=
macro
ProcessableMacro
.
processorWithDefaultRespServiceImpl
[
Req
,
Resp
,
Service
]
}
src/test/proto/schema.proto
浏览文件 @
8e4da614
//Test for Processable
//Test for Processable
and ProcessorCreator
syntax
=
"proto3"
;
option
java_package
=
"io.github.dreamylost.test.proto"
;
...
...
src/test/scala/io/github/dreamylost/Process
able
Test.scala
→
src/test/scala/io/github/dreamylost/Process
orCreator
Test.scala
浏览文件 @
8e4da614
...
...
@@ -21,59 +21,38 @@
package
io.github.dreamylost
import
com.alipay.sofa.jraft.rpc.
{
RpcContext
,
RpcRequestClosure
}
import
com.alipay.sofa.jraft.rpc.
{
RpcContext
,
RpcRequestClosure
,
RpcRequestProcessor
}
import
io.github.dreamylost.test.proto.BOpenSession.
{
BOpenSessionReq
,
BOpenSessionResp
}
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
import
java.util.concurrent.Executor
import
io.github.dreamylost.sofa.Processable
import
scala.jdk.CollectionConverters.MapHasAsScala
import
io.github.dreamylost.sofa.CustomRpcProcessor
/**
*
* @author 梦境迷离
* @version 1.0,2021/12/
3
* @version 1.0,2021/12/
6
*/
class
Process
able
Test
extends
AnyFlatSpec
with
Matchers
{
class
Process
orCreator
Test
extends
AnyFlatSpec
with
Matchers
{
// please exec `sbt compile` to generate java class fof the protobuf
// origin
"Processable1"
should
"compile ok"
in
{
val
openSession
:
CustomRpcProcessor
[
BOpenSessionReq
]
=
Processable
[
BOpenSessionReq
,
NetService
,
Executor
](
new
NetService
,
BOpenSessionResp
.
getDefaultInstance
,
(
command
:
Runnable
)
=>
???
)(
(
service
,
rpcRequestClosure
,
req
)
=>
{
import
scala.jdk.CollectionConverters.MapHasAsScala
val
username
=
req
.
getUsername
val
password
=
req
.
getPassword
val
configurationMap
=
req
.
getConfigurationMap
val
ret
=
service
.
openSession
(
username
,
password
,
configurationMap
.
asScala
.
toMap
)
BOpenSessionResp
.
newBuilder
().
setSessionHandle
(
ret
).
build
()
},
(
service
,
rpcContext
,
exception
)
=>
{
BOpenSessionResp
.
newBuilder
().
setStatus
(
exception
.
getLocalizedMessage
).
build
()
}
)
println
(
openSession
.
defaultResp
)
println
(
openSession
.
getClass
.
getClass
.
getName
)
println
(
openSession
.
interest
())
}
// // simple v1
"Processable2"
should
"compile ok"
in
{
val
openSession
:
CustomRpcProcessor
[
BOpenSessionReq
]
=
Processable
[
NetService
,
BOpenSessionReq
,
BOpenSessionResp
](
new
NetService
)(
(
service
,
_
,
req
)
=>
{
"ProcessorCreator1"
should
"compile ok"
in
{
implicit
val
service
=
new
NetService
implicit
val
executor
:
Executor
=
new
Executor
{
override
def
execute
(
command
:
Runnable
)
:
Unit
=
()
}
val
openSession
=
ProcessorCreator
[
RpcRequestClosure
,
RpcRequestProcessor
,
RpcContext
,
BOpenSessionReq
,
BOpenSessionResp
,
NetService
,
Executor
](
BOpenSessionResp
.
getDefaultInstance
,
(
service
,
rpcRequestClosure
,
req
)
=>
{
import
scala.jdk.CollectionConverters.MapHasAsScala
val
username
=
req
.
getUsername
val
password
=
req
.
getPassword
val
configurationMap
=
req
.
getConfigurationMap
val
ret
=
service
.
openSession
(
username
,
password
,
configurationMap
.
asScala
.
toMap
)
BOpenSessionResp
.
newBuilder
().
setSessionHandle
(
ret
).
build
()
},
(
_
,
_
,
exception
)
=>
{
(
service
,
rpcContext
,
exception
)
=>
{
BOpenSessionResp
.
newBuilder
().
setStatus
(
exception
.
getLocalizedMessage
).
build
()
}
)
...
...
@@ -85,11 +64,11 @@ class ProcessableTest extends AnyFlatSpec with Matchers {
println
(
openSession
.
interest
())
}
// simple v
2
"Process
able3
"
should
"compile ok"
in
{
// NetService must be a class and with an no parameter construction
val
openSession
:
CustomRpcProcessor
[
BOpenSessionReq
]
=
Processable
[
BOpenSessionReq
,
BOpenSessionResp
,
NetService
](
(
service
:
NetService
,
rpc
:
RpcRequestClosure
,
req
:
BOpenSessionR
eq
)
=>
{
// simple v
1
"Process
orCreator2
"
should
"compile ok"
in
{
implicit
val
service
=
new
NetService
val
openSession
=
ProcessorCreator
[
RpcRequestClosure
,
RpcRequestProcessor
,
RpcContext
,
BOpenSessionReq
,
BOpenSessionResp
,
NetService
](
(
service
,
_
,
r
eq
)
=>
{
import
scala.jdk.CollectionConverters.MapHasAsScala
val
username
=
req
.
getUsername
val
password
=
req
.
getPassword
...
...
@@ -97,7 +76,7 @@ class ProcessableTest extends AnyFlatSpec with Matchers {
val
ret
=
service
.
openSession
(
username
,
password
,
configurationMap
.
asScala
.
toMap
)
BOpenSessionResp
.
newBuilder
().
setSessionHandle
(
ret
).
build
()
},
(
service
:
NetService
,
rpc
:
RpcContext
,
exception
:
E
xception
)
=>
{
(
_
,
_
,
e
xception
)
=>
{
BOpenSessionResp
.
newBuilder
().
setStatus
(
exception
.
getLocalizedMessage
).
build
()
}
)
...
...
@@ -110,10 +89,11 @@ class ProcessableTest extends AnyFlatSpec with Matchers {
}
// simple v2
"Process
able4
"
should
"compile ok"
in
{
"Process
orCreator3
"
should
"compile ok"
in
{
// NetService must be a class and with an no parameter construction
val
openSession
:
CustomRpcProcessor
[
BOpenSessionReq
]
=
Processable
[
BOpenSessionReq
,
BOpenSessionResp
,
NetService
](
val
openSession
=
ProcessorCreator
[
NetService
,
RpcRequestClosure
,
RpcRequestProcessor
,
RpcContext
,
BOpenSessionReq
,
BOpenSessionResp
](
(
service
,
rpc
,
req
)
=>
{
import
scala.jdk.CollectionConverters.MapHasAsScala
val
username
=
req
.
getUsername
val
password
=
req
.
getPassword
val
configurationMap
=
req
.
getConfigurationMap
...
...
@@ -132,4 +112,66 @@ class ProcessableTest extends AnyFlatSpec with Matchers {
println
(
openSession
.
interest
())
}
// error
"ProcessorCreator4"
should
"compile error"
in
{
trait
Service
"""
| val openSession = ProcessorCreator[Service, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
| )
|
| println(openSession.defaultResp)
|
| println(openSession.getClass.getClass.getName)
|
| println(openSession.interest())
|"""
.
stripMargin
shouldNot
compile
}
// error
"ProcessorCreator5"
should
"compile error"
in
{
trait
Service
"""
| val openSession = ProcessorCreator[Service, RpcRequestProcessor, RpcRequestClosure, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
| )
|
| println(openSession.defaultResp)
|
| println(openSession.getClass.getClass.getName)
|
| println(openSession.interest())
|"""
.
stripMargin
shouldNot
compile
}
// error
"ProcessorCreator6"
should
"compile error"
in
{
object
Service
"""
| val openSession = ProcessorCreator[Service, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
| )
|
| println(openSession.defaultResp)
|
| println(openSession.getClass.getClass.getName)
|
| println(openSession.interest())
|"""
.
stripMargin
shouldNot
compile
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录