整理接口,去掉无用的接口,并调整返回值,升级与http相关的部分包(swagger-akka-http,swagger-jaxrs,akka-http)

This commit is contained in:
brightestboy 2019-03-19 20:29:12 +08:00
parent 2775de79e1
commit 286a8b593a
7 changed files with 256 additions and 425 deletions

View File

@ -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",

View 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>

View File

@ -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())
}

View File

@ -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+"未上链")
}
}
}

View File

@ -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] }
}
}
}
}

View File

@ -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")

View File

@ -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")
}