mirror of
https://gitee.com/BTAJL/repchain.git
synced 2024-12-02 11:48:10 +08:00
整理接口,去掉无用的接口,并调整返回值,升级与http相关的部分包(swagger-akka-http,swagger-jaxrs,akka-http)
This commit is contained in:
parent
2775de79e1
commit
286a8b593a
@ -5,7 +5,7 @@ version := "0.1"
|
||||
scalaVersion := "2.11.11"
|
||||
|
||||
lazy val akkaVersion = "2.5.3"
|
||||
val akkaHttpVersion = "10.0.9"
|
||||
val akkaHttpVersion = "10.0.11"
|
||||
|
||||
|
||||
|
||||
@ -55,8 +55,8 @@ libraryDependencies += "org.codehaus.janino" % "janino" % "2.6.1"
|
||||
libraryDependencies += "org.bouncycastle" % "bcprov-jdk15on" % "1.57"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"io.swagger" % "swagger-jaxrs" % "1.5.13",
|
||||
"com.github.swagger-akka-http" %% "swagger-akka-http" % "0.9.1",
|
||||
"io.swagger" % "swagger-jaxrs" % "1.5.21",
|
||||
"com.github.swagger-akka-http" %% "swagger-akka-http" % "0.13.0",
|
||||
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
|
||||
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
|
||||
"de.heikoseeberger" % "akka-http-json4s_2.11" % "1.16.1",
|
||||
|
34
scripts/api_req/assets6.xml
Normal file
34
scripts/api_req/assets6.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 Blockchain Technology and Application Joint Lab, Linkel Technology Co., Ltd, Beijing, Fintech Research Center of ISCAS.
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BA SIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
|
||||
<CSpec>
|
||||
<stype>2</stype>
|
||||
<chaincodename>ContractAssetsTPL</chaincodename>
|
||||
<chaincodeversion>1</chaincodeversion>
|
||||
<iptFunc>transfer</iptFunc>
|
||||
<iptArgs>
|
||||
{
|
||||
"from" : "121000005l35120456",
|
||||
"to" : "12110107bi45jh675g",
|
||||
"amount" : 5
|
||||
}
|
||||
</iptArgs>
|
||||
<timeout>0</timeout>
|
||||
<legal_prose></legal_prose>
|
||||
<code></code>
|
||||
<ctype>2</ctype>
|
||||
</CSpec>
|
@ -16,33 +16,28 @@
|
||||
|
||||
package rep.api
|
||||
|
||||
import scala.reflect.runtime.{universe=>ru}
|
||||
import akka.actor.ActorSystem
|
||||
import akka.stream.ActorMaterializer
|
||||
import com.github.swagger.akka._
|
||||
import com.github.swagger.akka.model.`package`.Info
|
||||
import com.github.swagger.akka.SwaggerHttpService
|
||||
import com.github.swagger.akka.model.Info
|
||||
import rep.api.rest._
|
||||
import io.swagger.models.ExternalDocs
|
||||
import io.swagger.models.auth.BasicAuthDefinition
|
||||
import rep.app.conf.SystemProfile
|
||||
|
||||
/**集成Swagger到AKKA HTTP
|
||||
* @author c4w
|
||||
* @constructor 创建提供Swagger文档服务的实例
|
||||
* @param system 传入的AKKA系统实例
|
||||
*
|
||||
* @author c4w
|
||||
* @constructor 创建提供Swagger文档服务的实例
|
||||
* @param system 传入的AKKA系统实例
|
||||
* @author zyf
|
||||
* @since 1.0
|
||||
*
|
||||
*/
|
||||
class SwaggerDocService(system: ActorSystem) extends SwaggerHttpService with HasActorSystem {
|
||||
override implicit val actorSystem: ActorSystem = system
|
||||
override implicit val materializer: ActorMaterializer = ActorMaterializer()
|
||||
override val apiTypes = Seq(
|
||||
ru.typeOf[ChainService],
|
||||
ru.typeOf[BlockService],
|
||||
ru.typeOf[TransactionService],
|
||||
ru.typeOf[CertService],
|
||||
ru.typeOf[LogMgrService],
|
||||
ru.typeOf[HashVerifyService])
|
||||
override val info = Info(version = "0.7")
|
||||
object SwaggerDocService extends SwaggerHttpService {
|
||||
override val apiClasses: Set[Class[_]] = Set(
|
||||
classOf[ChainService],
|
||||
classOf[BlockService],
|
||||
classOf[TransactionService],
|
||||
classOf[LogMgrService]
|
||||
)
|
||||
override val info = Info(version = "1.0")
|
||||
override val externalDocs = Some(new ExternalDocs("Developers Guide", "https://repchaindoc.readthedocs.io/zh/latest/index.html"))
|
||||
override val securitySchemeDefinitions = Map("basicAuth" -> new BasicAuthDefinition())
|
||||
}
|
@ -16,29 +16,18 @@
|
||||
|
||||
package rep.api.rest
|
||||
|
||||
import akka.actor.{ Actor, ActorLogging }
|
||||
import akka.actor.Actor
|
||||
import akka.util.Timeout
|
||||
import rep.protos.peer._
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.protobuf.timestamp.Timestamp
|
||||
import com.trueaccord.scalapb.json.JsonFormat
|
||||
import rep.utils.{ GlobalUtils, TimeUtils }
|
||||
import rep.network._
|
||||
import org.json4s._
|
||||
import rep.network._
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import akka.pattern.{ ask, pipe }
|
||||
import akka.pattern.ask
|
||||
|
||||
import scala.concurrent._
|
||||
import rep.sc.TransProcessor
|
||||
import rep.sc.TransProcessor._
|
||||
import rep.sc.Sandbox._
|
||||
import rep.protos.peer._
|
||||
import rep.protos.peer.Transaction._
|
||||
import rep.protos.peer.ChaincodeId._
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.protobuf.timestamp.Timestamp
|
||||
import rep.crypto._
|
||||
import rep.sc.Shim._
|
||||
import rep.network.PeerHelper._
|
||||
@ -53,32 +42,21 @@ import rep.network.tools.PeerExtension
|
||||
import rep.network.base.ModuleBase
|
||||
import rep.utils.GlobalUtils.ActorType
|
||||
import akka.actor.Props
|
||||
import akka.actor.Status._
|
||||
import rep.network.tools.PeerExtension
|
||||
import java.security.cert.Certificate
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.security.cert.CertificateFactory
|
||||
import rep.sc.Sandbox.SandboxException
|
||||
import rep.utils.SerializeUtils._
|
||||
import rep.sc.Shim
|
||||
import rep.utils.SerializeUtils
|
||||
import IdxPrefix._
|
||||
import java.util.Base64
|
||||
import rep.crypto.cert.SignTool
|
||||
import rep.log.trace._
|
||||
|
||||
|
||||
/**
|
||||
* RestActor伴生object,包含可接受的传入消息定义,以及处理的返回结果定义。
|
||||
* 以及用于建立Tranaction,检索Tranaction的静态方法
|
||||
* @author c4w created
|
||||
*
|
||||
*/
|
||||
* RestActor伴生object,包含可接受的传入消息定义,以及处理的返回结果定义。
|
||||
* 以及用于建立Tranaction,检索Tranaction的静态方法
|
||||
* @author c4w created
|
||||
*
|
||||
*/
|
||||
|
||||
object RestActor {
|
||||
def props(name: String): Props = Props(classOf[RestActor], name)
|
||||
case object ChainInfo
|
||||
|
||||
|
||||
case class SystemStart(cout: Int)
|
||||
case class SystemStop(from: Int, to: Int)
|
||||
|
||||
@ -88,33 +66,29 @@ object RestActor {
|
||||
case class TransactionId(txid: String)
|
||||
case class TransactionStreamId(txid: String)
|
||||
|
||||
case class PostResult(txid: String, result: Option[JValue], ol: List[Oper], err: Option[String])
|
||||
case class PostCert(cert: String, cid: String)
|
||||
case class PostAddr(addr: String, cid: String)
|
||||
case class PostHash(hash: String, cid: String)
|
||||
case class QueryHash(result: String)
|
||||
case class QueryAddr(addr: String, err: String)
|
||||
case class QueryCert(addr: String, cert: String, cid: String, err: String)
|
||||
case class PostResult(txid: String, result: Option[JValue], err: Option[String])
|
||||
case class QueryResult(result: Option[JValue])
|
||||
case class QueryCertAddr(addr: String)
|
||||
/*case class CSpec(stype: Int, idPath: String, idName: Option[String],
|
||||
|
||||
case class resultMsg(result: String)
|
||||
|
||||
/*case class CSpec(stype: Int, idPath: String, idName: Option[String],
|
||||
iptFunc: String, iptArgs: Seq[String], timeout: Int,
|
||||
secureContext: String, code: String, ctype: Int) */
|
||||
case class CSpec(stype: Int, chaincodename: String, chaincodeversion: Int,
|
||||
iptFunc: String, iptArgs: Seq[String], timeout: Int,legal_prose:String,
|
||||
code: String, ctype: Int)
|
||||
secureContext: String, code: String, ctype: Int) */
|
||||
case class CSpec(stype: Int, chaincodename: String, chaincodeversion: Int,
|
||||
iptFunc: String, iptArgs: Seq[String], timeout: Int,legal_prose:String,
|
||||
code: String, ctype: Int)
|
||||
case class tranSign(tran: String)
|
||||
|
||||
|
||||
case class closeOrOpen4Node(nodename:String,status:String)
|
||||
case class closeOrOpen4Package(nodename:String,packagename:String,status:String)
|
||||
case class ColseOrOpenAllLogger(status:String)
|
||||
case class ColseOrOpenTimeTrace(status:String)
|
||||
|
||||
/**
|
||||
* 根据节点名称和chainCode定义建立交易实例
|
||||
* @param nodeName 节点名称
|
||||
* @param c chainCode定义
|
||||
*/
|
||||
* 根据节点名称和chainCode定义建立交易实例
|
||||
* @param nodeName 节点名称
|
||||
* @param c chainCode定义
|
||||
*/
|
||||
def buildTranaction(nodeName: String, c: CSpec): Transaction = {
|
||||
val stype = c.stype match {
|
||||
case 1 =>
|
||||
@ -126,12 +100,11 @@ object RestActor {
|
||||
}
|
||||
val ctype = c.ctype match{
|
||||
case 1 =>
|
||||
rep.protos.peer.ChaincodeDeploy.CodeType.CODE_SCALA
|
||||
rep.protos.peer.ChaincodeDeploy.CodeType.CODE_SCALA
|
||||
case _ =>
|
||||
rep.protos.peer.ChaincodeDeploy.CodeType.CODE_JAVASCRIPT
|
||||
}
|
||||
|
||||
|
||||
|
||||
val chaincodeId = new ChaincodeId(c.chaincodename,c.chaincodeversion)
|
||||
if(stype==Transaction.Type.CHAINCODE_DEPLOY){
|
||||
PeerHelper.createTransaction4Deploy(nodeName, chaincodeId, c.code, c.legal_prose, c.timeout, ctype)
|
||||
@ -140,14 +113,14 @@ object RestActor {
|
||||
}else{
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 根据存储实例和交易id检索并返回交易Transaction
|
||||
* @param sr 存储实例
|
||||
* @param txId 交易id
|
||||
* @return 如果存在该交易,返回该交易;否则返回null
|
||||
*
|
||||
*/
|
||||
* @param sr 存储实例
|
||||
* @param txId 交易id
|
||||
* @return 如果存在该交易,返回该交易;否则返回null
|
||||
*
|
||||
*/
|
||||
def loadTransaction(sr: ImpDataAccess, txId: String): Option[Transaction] = {
|
||||
val bb = sr.getBlockByTxId(txId)
|
||||
bb match {
|
||||
@ -162,13 +135,14 @@ object RestActor {
|
||||
}
|
||||
|
||||
/**
|
||||
* RestActor负责处理rest api请求
|
||||
*
|
||||
*/
|
||||
* RestActor负责处理rest api请求
|
||||
*
|
||||
*/
|
||||
class RestActor extends Actor with ModuleHelper {
|
||||
|
||||
import RestActor._
|
||||
import spray.json._
|
||||
import rep.utils.Json4s.encodeJson
|
||||
import akka.http.scaladsl.model.{HttpResponse, MediaTypes,HttpEntity}
|
||||
|
||||
//import rep.utils.JsonFormat.AnyJsonFormat
|
||||
@ -177,120 +151,64 @@ class RestActor extends Actor with ModuleHelper {
|
||||
// val atp = getActorRef(ActorType.TRANSACTION_POOL)
|
||||
// println(s"atp:${atp}")
|
||||
val sr: ImpDataAccess = ImpDataAccess.GetDataAccess(pe.getSysTag)
|
||||
// val sTag = PeerExtension(context.system).getSysTag
|
||||
// val preload :ImpDataPreload = ImpDataPreloadMgr.GetImpDataPreload(sTag,"preload")
|
||||
// val sTag = PeerExtension(context.system).getSysTag
|
||||
// val preload :ImpDataPreload = ImpDataPreloadMgr.GetImpDataPreload(sTag,"preload")
|
||||
val sandbox = context.actorOf(TransProcessor.props("sandbox", "", self), "sandboxPost")
|
||||
val LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
val cert_begin = "-----BEGIN CERTIFICATE-----";
|
||||
val end_cert = "-----END CERTIFICATE-----";
|
||||
|
||||
|
||||
def preTransaction(t:Transaction) : Unit ={
|
||||
|
||||
val sig = t.signature.get.signature.toByteArray
|
||||
val tOutSig = t.clearSignature
|
||||
val certId = t.signature.get.certId.get
|
||||
try{
|
||||
|
||||
|
||||
SignTool.verify(sig, tOutSig.toByteArray, certId,pe.getSysTag) match {
|
||||
case true =>
|
||||
val future = sandbox ? PreTransaction(t)
|
||||
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||
val rv = result
|
||||
|
||||
ImpDataPreloadMgr.Free(pe.getDBTag,t.id)
|
||||
|
||||
rv.err match {
|
||||
case None =>
|
||||
//预执行正常,提交并广播交易
|
||||
getActorRef(ActorType.TRANSACTION_POOL) ! t // 给交易池发送消息 !=》告知(getActorRef)
|
||||
sender ! PostResult(t.id, Option(rv.r.asInstanceOf[JValue]), rv.ol, None) // 发送消息给调用者(sender)
|
||||
case Some(e) =>
|
||||
//预执行异常,废弃交易,向api调用者发送异常
|
||||
sender ! e
|
||||
val sig = t.signature.get.signature.toByteArray
|
||||
val tOutSig = t.clearSignature
|
||||
val certId = t.signature.get.certId.get
|
||||
try{
|
||||
SignTool.verify(sig, tOutSig.toByteArray, certId,pe.getSysTag) match {
|
||||
case true =>
|
||||
val future = sandbox ? PreTransaction(t)
|
||||
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||
val rv = result
|
||||
// 释放存储实例
|
||||
ImpDataPreloadMgr.Free(pe.getDBTag,t.id)
|
||||
rv.err match {
|
||||
case None =>
|
||||
if (rv.r.reason.isEmpty) {
|
||||
//预执行正常,提交并广播交易
|
||||
getActorRef(ActorType.TRANSACTION_POOL) ! t // 给交易池发送消息 !=》告知(getActorRef)
|
||||
}
|
||||
case false => throw new RuntimeException("验证签名出错")
|
||||
sender ! PostResult(t.id, Option(encodeJson(rv.r)), None)
|
||||
case Some(err) =>
|
||||
//预执行异常,废弃交易,向api调用者发送异常
|
||||
sender ! err
|
||||
}
|
||||
|
||||
}catch{
|
||||
case e : RuntimeException =>
|
||||
sender ! PostResult(t.id, None, null, Option(e.getMessage))
|
||||
case false => throw new RuntimeException("验证签名出错")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}catch{
|
||||
case e : RuntimeException =>
|
||||
sender ! PostResult(t.id, None, Option(e.getMessage))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def receive: Receive = {
|
||||
// TODO test_zyf 处理post 带签名交易请求 测试用,添加API
|
||||
|
||||
case tranSign(tr: String) =>
|
||||
val tr1 = BytesHex.hex2bytes(tr) // 解析交易编码后的16进制字符串,进行解码16进制反解码decode
|
||||
try {
|
||||
val txr = Transaction.parseFrom(tr1)
|
||||
preTransaction(txr)
|
||||
val txr = Transaction.parseFrom(tr1)
|
||||
preTransaction(txr)
|
||||
} catch {
|
||||
case e:Exception =>
|
||||
//println (e.getMessage)
|
||||
//throw e
|
||||
sender ! PostResult("", None, null, Option("transcation parser error!"))
|
||||
sender ! PostResult("", None, Option(s"transcation parser error! + ${e.getMessage}"))
|
||||
}
|
||||
|
||||
//TODO 做交易的签名验证,是否能在信任列表或kv中找到证书,如果找到验证一下,如果没有找到,则返回错误
|
||||
/*val sig = txr.signature.toByteArray
|
||||
val tOutSig1 = txr.withSignature(ByteString.EMPTY)
|
||||
val tOutSig = tOutSig1.withMetadata(ByteString.EMPTY)
|
||||
val cid = ChaincodeID.fromAscii(txr.chaincodeID.toStringUtf8).name
|
||||
val certKey = WorldStateKeyPreFix + cid + "_" + PRE_CERT + txr.cert.toStringUtf8
|
||||
try{
|
||||
var cert = ECDSASign.getCertWithCheck(txr.cert.toStringUtf8,certKey,pe.getSysTag)
|
||||
if(cert != None){
|
||||
ECDSASign.verify(sig, PeerHelper.getTxHash(tOutSig), cert.get.getPublicKey) match {
|
||||
case true =>
|
||||
case false => throw new RuntimeException("验证签名出错")
|
||||
}
|
||||
}else{
|
||||
throw new RuntimeException("没有证书")
|
||||
}
|
||||
}catch{
|
||||
case e : RuntimeException =>
|
||||
sender ! PostResult(txr.txid, None, null, Option(e.getMessage))
|
||||
}
|
||||
|
||||
try {
|
||||
val future = sandbox ? PreTransaction(txr)
|
||||
val result = Await.result(future, timeout.duration).asInstanceOf[DoTransactionResult]
|
||||
val rv = result
|
||||
rv.err match {
|
||||
case None =>
|
||||
//预执行正常,提交并广播交易
|
||||
getActorRef(ActorType.TRANSACTION_POOL) ! txr
|
||||
sender ! PostResult(txr.txid, Option(rv.r.asInstanceOf[JValue]), rv.ol, None) // 发送消息给调用者(sender)
|
||||
case Some(e) =>
|
||||
//预执行异常,废弃交易,向api调用者发送异常
|
||||
//c4w 4.11
|
||||
//sender ! e
|
||||
sender ! PostResult(txr.txid,None, null, Option(e.cause.toString()))
|
||||
}
|
||||
} catch {
|
||||
case esig:java.security.SignatureException =>
|
||||
sender ! PostResult(txr.txid, None, null, Option(esig.getMessage+":无效的签名"))
|
||||
case e:RuntimeException =>
|
||||
// val fail = Failure(new SandboxException("hahahahahahaha")) // 在evserver中有个拦截一样的,貌似只能接受SandboxException
|
||||
// sender ! fail
|
||||
sender ! PostResult(txr.txid, None, null, Option(e.getMessage))
|
||||
case _:Exception =>
|
||||
sender ! PostResult(txr.txid, None, null, Option("未知错误"))
|
||||
}*/
|
||||
|
||||
//处理post CSpec构造交易的请求
|
||||
case c: CSpec =>
|
||||
//构建transaction并通过peer广播
|
||||
println(pe.getSysTag) // test_zyf
|
||||
val t = buildTranaction(pe.getSysTag, c)
|
||||
preTransaction(t)
|
||||
|
||||
// 流式提交交易
|
||||
case t: Transaction =>
|
||||
preTransaction(t)
|
||||
|
||||
case SystemStart(cout) =>
|
||||
val rs = TestMain.startSystem(cout)
|
||||
val r = rs match {
|
||||
@ -309,6 +227,78 @@ class RestActor extends Actor with ModuleHelper {
|
||||
}
|
||||
sender ! r
|
||||
|
||||
|
||||
case ColseOrOpenTimeTrace(status) =>
|
||||
var remsg = ""
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
RepTimeTracer.openTimeTrace
|
||||
remsg = "已经打开运行时间跟踪"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
RepTimeTracer.closeTimeTrace
|
||||
remsg = "已经关闭运行时间跟踪"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! resultMsg(remsg)
|
||||
|
||||
case ColseOrOpenAllLogger(status) =>
|
||||
var remsg = ""
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.openAllTrace
|
||||
remsg = "已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.closeAllTrace
|
||||
remsg = "已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! resultMsg(remsg)
|
||||
|
||||
case closeOrOpen4Node(nodename,status) =>
|
||||
var remsg = ""
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.openNodeLog(nodename)
|
||||
remsg = "节点="+nodename+",已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.closeNodeLog(nodename)
|
||||
remsg = "节点="+nodename+",已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! resultMsg(remsg)
|
||||
|
||||
case closeOrOpen4Package(nodename,packagename,status) =>
|
||||
var remsg = ""
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.setModuleLogOption(nodename, packagename, true)
|
||||
remsg = "包名="+packagename+",已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.setModuleLogOption(nodename, packagename, false)
|
||||
remsg = "包名="+packagename+",已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! resultMsg(remsg)
|
||||
|
||||
// 根据高度检索块
|
||||
case BlockHeight(h) =>
|
||||
val bb = sr.getBlockByHeight(h)
|
||||
val r = bb match {
|
||||
case null => QueryResult(None)
|
||||
case _ =>
|
||||
val bl = Block.parseFrom(bb)
|
||||
QueryResult(Option(JsonFormat.toJson(bl)))
|
||||
}
|
||||
sender ! r
|
||||
|
||||
// 根据高度检索块的子节流
|
||||
case BlockHeightStream(h) =>
|
||||
val bb = sr.getBlockByHeight(h)
|
||||
val body = akka.util.ByteString(bb)
|
||||
val entity = HttpEntity.Strict(MediaTypes.`application/octet-stream`, body)
|
||||
val httpResponse = HttpResponse(entity = entity)
|
||||
sender ! httpResponse
|
||||
|
||||
//根据block hash检索
|
||||
case BlockId(bid) =>
|
||||
val bb = sr.getBlockByBase64Hash(bid)
|
||||
@ -319,82 +309,8 @@ class RestActor extends Actor with ModuleHelper {
|
||||
QueryResult(Option(JsonFormat.toJson(bl)))
|
||||
}
|
||||
sender ! r
|
||||
|
||||
|
||||
|
||||
case ColseOrOpenTimeTrace(status) =>
|
||||
var remsg = "";
|
||||
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
RepTimeTracer.openTimeTrace
|
||||
remsg = "已经打开运行时间跟踪"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
RepTimeTracer.closeTimeTrace
|
||||
remsg = "已经关闭运行时间跟踪"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! QueryHash(remsg)
|
||||
|
||||
case ColseOrOpenAllLogger(status) =>
|
||||
var remsg = "";
|
||||
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.openAllTrace
|
||||
remsg = "已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.closeAllTrace
|
||||
remsg = "已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! QueryHash(remsg)
|
||||
|
||||
case closeOrOpen4Node(nodename,status) =>
|
||||
var remsg = "";
|
||||
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.openNodeLog(nodename)
|
||||
remsg = "节点="+nodename+",已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.closeNodeLog(nodename)
|
||||
remsg = "节点="+nodename+",已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! QueryHash(remsg)
|
||||
|
||||
case closeOrOpen4Package(nodename,packagename,status) =>
|
||||
var remsg = "";
|
||||
if(status.equalsIgnoreCase("on")){
|
||||
LogOption.setModuleLogOption(nodename, packagename, true)
|
||||
remsg = "包名="+packagename+",已经打开日志输出"
|
||||
}else if(status.equalsIgnoreCase("off")){
|
||||
LogOption.setModuleLogOption(nodename, packagename, false)
|
||||
remsg = "包名="+packagename+",已经关闭日志输出"
|
||||
}else{
|
||||
remsg = "状态只能输入on/off"
|
||||
}
|
||||
sender ! QueryHash(remsg)
|
||||
|
||||
|
||||
case BlockHeight(h) =>
|
||||
val bb = sr.getBlockByHeight(h)
|
||||
val r = bb match {
|
||||
case null => QueryResult(None)
|
||||
case _ =>
|
||||
val bl = Block.parseFrom(bb)
|
||||
QueryResult(Option(JsonFormat.toJson(bl)))
|
||||
}
|
||||
sender ! r
|
||||
|
||||
case BlockHeightStream(h) =>
|
||||
val bb = sr.getBlockByHeight(h)
|
||||
val body = akka.util.ByteString(bb)
|
||||
val entity = HttpEntity.Strict(MediaTypes.`application/octet-stream`, body)
|
||||
val httpResponse = HttpResponse(entity = entity)
|
||||
sender ! httpResponse
|
||||
|
||||
// 根据txid检索交易
|
||||
case TransactionId(txId) =>
|
||||
var r = loadTransaction(sr, txId) match {
|
||||
case None =>
|
||||
@ -404,76 +320,20 @@ class RestActor extends Actor with ModuleHelper {
|
||||
}
|
||||
sender ! r
|
||||
|
||||
|
||||
// 根据txid检索交易字节流
|
||||
case TransactionStreamId(txId) =>
|
||||
val r = loadTransaction(sr, txId)
|
||||
val t = r.get
|
||||
val body = akka.util.ByteString(t.toByteArray)
|
||||
val entity = HttpEntity.Strict(MediaTypes.`application/octet-stream`, body)
|
||||
val httpResponse = HttpResponse(entity = entity)
|
||||
val entity = HttpEntity.Strict(MediaTypes.`application/octet-stream`, body)
|
||||
val httpResponse = HttpResponse(entity = entity)
|
||||
sender ! httpResponse
|
||||
|
||||
// 获取链信息
|
||||
case ChainInfo =>
|
||||
val cij = JsonFormat.toJson(sr.getBlockChainInfo)
|
||||
sender ! QueryResult(Option(cij))
|
||||
|
||||
case PostCert(pemcert,cid) =>
|
||||
val cf = CertificateFactory.getInstance("X.509");
|
||||
try {
|
||||
val cert = cf.generateCertificate(
|
||||
new ByteArrayInputStream(
|
||||
Base64.getDecoder.decode(pemcert)
|
||||
)
|
||||
)
|
||||
println(cert.toString())
|
||||
val certByte = SerializeUtils.serialise(cert)
|
||||
//todo 不知道是否需要返回
|
||||
//val certaddr = ECDSASign.getBitcoinAddrByCert(certByte)
|
||||
//sender ! QueryAddr(certaddr, "")
|
||||
} catch {
|
||||
case e:Exception =>
|
||||
sender ! QueryAddr("", "证书字符串错误")
|
||||
}
|
||||
|
||||
|
||||
|
||||
case pa: PostAddr =>
|
||||
//todo 不知道是否需要返回
|
||||
//TODO 从短地址到证书得有信任列表里的,还有就是ws中存储的,两个都得做,如果证书在,返回证书字符串
|
||||
/*try{
|
||||
var peercert : Option[Certificate] = None
|
||||
try{
|
||||
peercert = ECDSASign.getCertByBitcoinAddr(pa.addr)
|
||||
}catch{
|
||||
case el : Exception =>
|
||||
}
|
||||
val certKey = WorldStateKeyPreFix + pa.cid + "_" + PRE_CERT + pa.addr
|
||||
val kvcer = Option(sr.Get(certKey))
|
||||
if(peercert != None) {
|
||||
val pemCertPre = new String(Base64.getEncoder.encode(peercert.get.getEncoded))
|
||||
val pemcertstr = cert_begin + LINE_SEPARATOR + pemCertPre + LINE_SEPARATOR + end_cert
|
||||
sender ! QueryCert(pa.addr, pemcertstr, pa.cid, "")
|
||||
} else if (kvcer != None){
|
||||
if (new String(kvcer.get) == "null") {
|
||||
throw new RuntimeException("该用户证书已注销")
|
||||
}
|
||||
val kvcert = SerializeUtils.deserialise(kvcer.get).asInstanceOf[Certificate]
|
||||
val pemCertPre = new String(Base64.getEncoder.encode(kvcert.getEncoded))
|
||||
val pemcertstr = cert_begin + LINE_SEPARATOR + pemCertPre + LINE_SEPARATOR + end_cert
|
||||
sender ! QueryCert(pa.addr, pemcertstr, pa.cid, "")
|
||||
} else {
|
||||
sender ! QueryCert(pa.addr, "", pa.cid, "不存在证书")
|
||||
}
|
||||
}catch{
|
||||
case e : Exception => sender ! QueryCert(pa.addr, "", pa.cid, e.getMessage)
|
||||
}*/
|
||||
|
||||
// TODO 主要是查询hash是否存在
|
||||
case ph: PostHash =>
|
||||
val pre_key = WorldStateKeyPreFix + ph.cid + "_"
|
||||
val res = deserialiseJson(sr.Get(pre_key + ph.hash))
|
||||
if(res != null) {
|
||||
sender ! QueryHash(ph.hash+"已存在")
|
||||
} else {
|
||||
sender ! QueryHash("当前"+ph.hash+"未上链")
|
||||
}
|
||||
}
|
||||
}
|
@ -73,11 +73,11 @@ class LogMgrService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
new ApiImplicitParam(name = "status", value = "on/off", required = true, dataType = "string", paramType = "path")
|
||||
))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "返回日志打开关闭结果", response = classOf[QueryHash])))
|
||||
new ApiResponse(code = 200, message = "返回日志打开关闭结果", response = classOf[resultMsg])))
|
||||
def openOrCloseLogger =
|
||||
path("logmgr"/"openorclose4all"/ Segment) { status =>
|
||||
get {
|
||||
complete { (ra ? ColseOrOpenAllLogger(status)).mapTo[QueryHash] }
|
||||
complete { (ra ? ColseOrOpenAllLogger(status)).mapTo[resultMsg] }
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,11 +87,11 @@ class LogMgrService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
new ApiImplicitParam(name = "status", value = "on/off", required = true, dataType = "string", paramType = "path")
|
||||
))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "打开或者关闭系统运行时间跟踪", response = classOf[QueryHash])))
|
||||
new ApiResponse(code = 200, message = "打开或者关闭系统运行时间跟踪", response = classOf[resultMsg])))
|
||||
def openorclosestatistime =
|
||||
path("logmgr"/"openorclosestatistime"/ Segment) { status =>
|
||||
get {
|
||||
complete { (ra ? ColseOrOpenTimeTrace(status)).mapTo[QueryHash] }
|
||||
complete { (ra ? ColseOrOpenTimeTrace(status)).mapTo[resultMsg] }
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,12 +100,12 @@ class LogMgrService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "body", value = "打开/关闭某个节点的日志", required = true, dataTypeClass = classOf[closeOrOpen4Node], paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "该节点已经打开或关闭", response = classOf[QueryHash])))
|
||||
new ApiResponse(code = 200, message = "该节点已经打开或关闭", response = classOf[resultMsg])))
|
||||
def openorclose4node =
|
||||
path("logmgr" / "openorclose4node") {
|
||||
post {
|
||||
entity(as[closeOrOpen4Node]) { closeOrOpen4Node =>
|
||||
complete { (ra ? closeOrOpen4Node).mapTo[QueryHash] }
|
||||
complete { (ra ? closeOrOpen4Node).mapTo[resultMsg] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,12 +116,12 @@ class LogMgrService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "body", value = "打开/关闭某个包的日志", required = true, dataTypeClass = classOf[closeOrOpen4Package], paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "该包已经打开或关闭", response = classOf[QueryHash])))
|
||||
new ApiResponse(code = 200, message = "该包已经打开或关闭", response = classOf[resultMsg])))
|
||||
def openorclose4package =
|
||||
path("logmgr" / "openorclose4package") {
|
||||
post {
|
||||
entity(as[closeOrOpen4Package]) { closeOrOpen4Package =>
|
||||
complete { (ra ? closeOrOpen4Package).mapTo[QueryHash] }
|
||||
complete { (ra ? closeOrOpen4Package).mapTo[resultMsg] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,7 +133,6 @@ class LogMgrService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
/** 获得区块链的概要信息
|
||||
* @author c4w
|
||||
*/
|
||||
|
||||
@Api(value = "/chaininfo", description = "获得当前区块链信息", produces = "application/json")
|
||||
@Path("chaininfo")
|
||||
class ChainService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ -222,7 +221,6 @@ class BlockService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
/** 获得指定交易的详细信息,提交签名交易
|
||||
* @author c4w
|
||||
*/
|
||||
|
||||
@Api(value = "/transaction", description = "获得交易数据", consumes = "application/json,application/xml", produces = "application/json,application/xml")
|
||||
@Path("transaction")
|
||||
class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
@ -280,6 +278,7 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
complete { (ra ? TransactionId(transactionId)).mapTo[QueryResult] }
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/stream/{transactionId}")
|
||||
@ApiOperation(value = "返回指定id的交易字节流", notes = "", nickname = "getTransactionStream", httpMethod = "GET", produces = "application/octet-stream")
|
||||
@ApiImplicitParams(Array(
|
||||
@ -292,6 +291,7 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
complete( (ra ? TransactionStreamId(transactionId)).mapTo[HttpResponse])
|
||||
}
|
||||
}
|
||||
|
||||
//以十六进制字符串提交签名交易
|
||||
@Path("/postTranByString")
|
||||
@ApiOperation(value = "提交带签名的交易", notes = "", nickname = "postSignTransaction", httpMethod = "POST")
|
||||
@ -304,8 +304,6 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
path("transaction" / "postTranByString") {
|
||||
post {
|
||||
entity(as[String]) { trans =>
|
||||
//str=>
|
||||
//complete(OK, trans)
|
||||
complete { (ra ? tranSign(trans)).mapTo[PostResult] }
|
||||
}
|
||||
}
|
||||
@ -358,81 +356,4 @@ class TransactionService(ra: ActorRef)(implicit executionContext: ExecutionConte
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Api(value = "/certAddr", description = "获得证书短地址", produces = "application/json")
|
||||
@Path("certAddr")
|
||||
class CertService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
extends Directives {
|
||||
|
||||
import akka.pattern.ask
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import Json4sSupport._
|
||||
implicit val serialization = jackson.Serialization // or native.Serialization
|
||||
implicit val formats = DefaultFormats
|
||||
implicit val timeout = Timeout(20.seconds)
|
||||
|
||||
val route = getAddrByCert ~ getCertByAddr
|
||||
|
||||
@Path("/getAddrByCert")
|
||||
@ApiOperation(value = "返回证书短地址", notes = "", nickname = "getAddrByCert", httpMethod = "POST")
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "body", value = "证书", required = true, dataTypeClass = classOf[PostCert], paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "查询证书短地址", response = classOf[QueryAddr])))
|
||||
def getAddrByCert =
|
||||
path("certAddr" / "getAddrByCert") {
|
||||
post {
|
||||
entity(as[PostCert]) { PostCert =>
|
||||
complete { (ra ? PostCert).mapTo[QueryAddr] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/getCertByAddr")
|
||||
@ApiOperation(value = "返回证书字符串", notes = "", nickname = "getCertByAddr", httpMethod = "POST")
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "body", value = "短地址", required = true, dataTypeClass = classOf[PostAddr], paramType = "body")))
|
||||
@ApiResponses(Array(
|
||||
new ApiResponse(code = 200, message = "查询证书字符串", response = classOf[QueryCert])))
|
||||
def getCertByAddr =
|
||||
path("certAddr" / "getCertByAddr") {
|
||||
post {
|
||||
entity(as[PostAddr]) { PostAddr =>
|
||||
complete { (ra ? PostAddr).mapTo[QueryCert] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Api(value = "/hash", description = "验证hash是否存在", produces = "application/json")
|
||||
@Path("hash")
|
||||
class HashVerifyService(ra: ActorRef)(implicit executionContext: ExecutionContext)
|
||||
extends Directives {
|
||||
|
||||
import akka.pattern.ask
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import Json4sSupport._
|
||||
implicit val serialization = jackson.Serialization // or native.Serialization
|
||||
implicit val formats = DefaultFormats
|
||||
implicit val timeout = Timeout(20.seconds)
|
||||
|
||||
val route = verifyImageHash
|
||||
|
||||
@Path("/verifyHash")
|
||||
@ApiOperation(value = "返回hash是否存在", notes = "", nickname = "verifyHash", httpMethod = "POST")
|
||||
@ApiImplicitParams(Array(
|
||||
new ApiImplicitParam(name = "body", value = "hash值与cid", required = true, dataTypeClass = classOf[PostHash], paramType = "body")))
|
||||
@ApiResponses(Array(new ApiResponse(code = 200, message = "验证hash值", response = classOf[QueryHash])))
|
||||
def verifyImageHash =
|
||||
path("hash" / "verifyHash") {
|
||||
post {
|
||||
entity(as[PostHash]) { PostHash =>
|
||||
complete { (ra ? PostHash).mapTo[QueryHash] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,15 +15,20 @@
|
||||
*/
|
||||
package rep.crypto.cert
|
||||
|
||||
import java.security.{ PrivateKey, PublicKey, KeyStore }
|
||||
import java.security.cert.{ Certificate, CertificateFactory }
|
||||
import java.security.{KeyStore, PrivateKey, PublicKey}
|
||||
import java.security.cert.{Certificate, CertificateFactory, X509Certificate}
|
||||
|
||||
import rep.protos.peer.CertId
|
||||
|
||||
import scala.collection.mutable
|
||||
import java.io._
|
||||
import java.util.{ ArrayList, List }
|
||||
import java.util.{ArrayList, List}
|
||||
|
||||
import rep.app.conf.SystemProfile
|
||||
|
||||
import scala.util.control.Breaks._
|
||||
import fastparse.utils.Base64
|
||||
import org.bouncycastle.util.io.pem.PemReader
|
||||
|
||||
/**
|
||||
* 负责签名和验签的工具了,所有相关的功能都调用该类
|
||||
@ -177,6 +182,24 @@ object SignTool {
|
||||
Base64.Decoder(pemcert.replaceAll("\r\n", "").stripPrefix("-----BEGIN CERTIFICATE-----").stripSuffix("-----END CERTIFICATE-----")).toByteArray))
|
||||
cert
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据pem字符串生成证书
|
||||
* @param certPem
|
||||
* @return
|
||||
*/
|
||||
def generateX509CertByPem(certPem: String): Option[X509Certificate] = {
|
||||
try {
|
||||
val cf = CertificateFactory.getInstance("X.509")
|
||||
val pemReader = new PemReader(new StringReader(certPem))
|
||||
val certByte = pemReader.readPemObject().getContent()
|
||||
val x509Cert = cf.generateCertificate(new ByteArrayInputStream(certByte))
|
||||
Some(x509Cert.asInstanceOf[X509Certificate])
|
||||
} catch {
|
||||
case ex: Exception =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def getCertByFile(path:String):Certificate = {
|
||||
val certF = CertificateFactory.getInstance("X.509")
|
||||
|
@ -51,15 +51,15 @@ import rep.app.conf.SystemProfile
|
||||
*/
|
||||
object EventServer {
|
||||
|
||||
implicit def myExceptionHandler = ExceptionHandler {
|
||||
//合约执行异常,回送HTTP 200,包容chrome的跨域尝试
|
||||
case e: SandboxException =>
|
||||
extractUri { uri =>
|
||||
complete(HttpResponse(Accepted,
|
||||
implicit def myExceptionHandler = ExceptionHandler {
|
||||
//合约执行异常,回送HTTP 200,包容chrome的跨域尝试
|
||||
case e: SandboxException =>
|
||||
extractUri { uri =>
|
||||
complete(HttpResponse(Accepted,
|
||||
entity = HttpEntity(ContentTypes.`application/json`,
|
||||
s"""{"err": "${e.getMessage}"}"""))
|
||||
)
|
||||
}
|
||||
s"""{"err": "${e.getMessage}"}"""))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** 启动Event服务
|
||||
@ -69,9 +69,9 @@ implicit def myExceptionHandler = ExceptionHandler {
|
||||
* @param port 指定侦听的端口
|
||||
*/
|
||||
def start(sys:ActorSystem ,port:Int) {
|
||||
implicit val _ = sys.dispatcher
|
||||
implicit val system =sys
|
||||
implicit val materializer = ActorMaterializer()
|
||||
implicit val executionContext = system.dispatcher
|
||||
|
||||
//提供静态文件的web访问服务
|
||||
val route_evt =
|
||||
@ -95,16 +95,14 @@ implicit def myExceptionHandler = ExceptionHandler {
|
||||
val ra = sys.actorOf(Props[RestActor],"api")
|
||||
//允许跨域访问,以支持在应用中发起请求
|
||||
Http().bindAndHandle(
|
||||
route_evt
|
||||
~ cors() {new BlockService(ra).route }
|
||||
~ cors() {new LogMgrService(ra).route }
|
||||
~ cors() {new ChainService(ra).route }
|
||||
~ cors() {new TransactionService(ra).route }
|
||||
~ cors() {new CertService(ra).route }
|
||||
~ cors() {new HashVerifyService(ra).route }
|
||||
~ new SwaggerDocService(sys).routes
|
||||
|
||||
,"0.0.0.0", port)
|
||||
route_evt
|
||||
~ cors() (
|
||||
new BlockService(ra).route ~
|
||||
new LogMgrService(ra).route ~
|
||||
new ChainService(ra).route ~
|
||||
new TransactionService(ra).route ~
|
||||
SwaggerDocService.routes),
|
||||
"0.0.0.0", port)
|
||||
println(s"Event Server online at http://localhost:$port")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user