Add Akka sanity check #519

This commit is contained in:
Marko Milic 2017-04-19 15:21:28 +02:00
parent dee5be7afe
commit 4033a01ca3
13 changed files with 124 additions and 21 deletions

View File

@ -28,6 +28,8 @@ remotedata.enable=false
remotedata.hostname=10.0.0.19
# Arbitrary port of your choosing
remotedata.port=5448
# Arbitrary value used in order to assure us that remote and local sides are paired well
remotedata.secret=secret
# Optionally configure postgres, otherwise file-based H2 will be used
remotedata.db.driver=org.postgresql.Driver

View File

@ -92,6 +92,8 @@ db.url=jdbc:postgresql://localhost:5432/dbname?user=dbusername&password=thepassw
#remotedata.enable=true
#remotedata.hostname=127.0.0.1
#remotedata.port=2662
# Arbitrary value used in order to assure us that remote and local sides are paired well
#remotedata.secret=secret
## Set separate database for data split
## If remotedata is disabled, bd has to be accessible from local machine

View File

@ -45,6 +45,14 @@ hostname=http://localhost:8016
#if you want to change the port when running via the command line, use "mvn -Djetty.port=8089 jetty:run" instead
tests.port=8016
## Enable remote Akka actor for data split
## If set to true, must set hostname and port
## of remote machine
#remotedata.enable=false
#remotedata.hostname=127.0.0.1
#remotedata.port=2662
# Arbitrary value used in order to assure us that remote and local sides are paired well
remotedata.secret=secret
End of minimum settings
####################################

View File

@ -40,6 +40,7 @@ import code.api.Constant._
import code.api.ResourceDocs1_4_0.ResourceDocs
import code.api._
import code.api.sandbox.SandboxApiCalls
import code.api.util.{APIUtil, ErrorMessages}
import code.atms.MappedAtm
import code.branches.MappedBranch
import code.cards.{MappedPhysicalCard, PinReset}
@ -374,6 +375,13 @@ class Boot extends Loggable{
TransactionStatusScheduler.start(delay)
}
APIUtil.akkaSanityCheck() match {
case Full(c) if c == true => logger.info(s"remotedata.secret matched = $c")
case Full(c) if c == false => throw new Exception(ErrorMessages.RemoteDataSecretMatchError)
case Empty => throw new Exception(ErrorMessages.RemoteDataSecretObtainError)
case _ => throw new Exception(s"Unexpected error occurs during Akka sanity check!")
}
}
def schemifyAll() = {

View File

@ -1,6 +1,7 @@
package code.api.ResourceDocs1_4_0
import code.api.util.APIUtil
import code.api.v1_2_1.Akka
import code.api.v1_4_0.{APIMethods140, JSONFactory1_4_0, OBPAPI1_4_0}
import code.api.v2_2_0.{APIMethods220, OBPAPI2_2_0}
import code.bankconnectors.{KafkaJSONFactory_vMar2017, KafkaMappedConnector_vMar2017}
@ -302,7 +303,7 @@ def filterResourceDocs(allResources: List[ResourceDoc]) : List[ResourceDoc] = {
user =>
val apiDetails: JValue = {
val hostedBy = new HostedBy("Dummy Org", "contact@example.com", "12345")
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, "dummy-connector", hostedBy)
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, "dummy-connector", hostedBy, Akka(APIUtil.akkaSanityCheck()))
Extraction.decompose(apiInfoJSON)
}

View File

@ -44,6 +44,7 @@ import code.customer.Customer
import code.entitlement.Entitlement
import code.metrics.{APIMetrics, ConnMetrics}
import code.model._
import code.sanitycheck.SanityCheck
import dispatch.url
import net.liftweb.common.{Empty, _}
import net.liftweb.http.js.JE.JsRaw
@ -108,6 +109,9 @@ object ErrorMessages {
val InsufficientAuthorisationToCreateBranch = "OBP-20019: Insufficient authorisation to Create Branch offered by the bank. The Request could not be created because you don't have access to CanCreateBranch."
val InsufficientAuthorisationToCreateBank = "OBP-20020: Insufficient authorisation to Create Bank. The Request could not be created because you don't have access to CanCreateBank."
val RemoteDataSecretMatchError = "OBP-20021: Remote data secret cannot be matched!"
val RemoteDataSecretObtainError = "OBP-20021: Remote data secret cannot be obtained!"
// Resource related messages
val BankNotFound = "OBP-30001: Bank not found. Please specify a valid value for BANK_ID."
@ -926,4 +930,9 @@ Returns a string showed to the developer
result
}
def akkaSanityCheck (): Box[Boolean] = {
val remoteDataSecret = Props.get("remotedata.secret").openOrThrowException("Cannot obtain property remotedata.secret")
SanityCheck.sanityCheck.vend.remoteAkkaSanityCheck(remoteDataSecret)
}
}

View File

@ -1,25 +1,21 @@
package code.api.v1_2_1
import java.net.URL
import code.api.util.APIUtil
import code.api.util.APIUtil._
import code.bankconnectors.{OBPFromDate, OBPOffset, OBPToDate, _}
import code.metadata.counterparties.Counterparties
import code.model.{CreateViewJSON, UpdateViewJSON, _}
import code.sanitycheck.SanityCheck
import net.liftweb.common.{Full, _}
import net.liftweb.http.rest.RestHelper
import net.liftweb.http.{JsonResponse, Req}
import net.liftweb.json.Extraction
import net.liftweb.common._
import code.model._
import net.liftweb.json.Extraction._
import net.liftweb.json.JsonAST.JValue
import APIUtil._
import net.liftweb.util.Helpers._
import net.liftweb.http.rest.RestHelper
import java.net.URL
import net.liftweb.util.{True, Props}
import code.bankconnectors._
import code.bankconnectors.OBPOffset
import code.bankconnectors.OBPFromDate
import code.bankconnectors.OBPToDate
import code.metadata.counterparties.Counterparties
import code.model.CreateViewJSON
import net.liftweb.common.Full
import code.model.UpdateViewJSON
import net.liftweb.util.Props
import scala.collection.immutable.Nil
import scala.collection.mutable.ArrayBuffer
@ -82,7 +78,7 @@ trait APIMethods121 {
val connector = Props.get("connector").openOrThrowException("no connector set")
val hostedBy = new HostedBy(organisation, email, phone)
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, connector, hostedBy)
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, connector, hostedBy, Akka(APIUtil.akkaSanityCheck()))
Extraction.decompose(apiInfoJSON)
}
apiDetails

View File

@ -40,13 +40,15 @@ case class APIInfoJSON(
version_status: String,
git_commit : String,
connector : String,
hosted_by : HostedBy
hosted_by : HostedBy,
akka: Akka
)
case class HostedBy(
organisation : String,
email : String,
phone : String
)
case class Akka(remote_data_secret_matched: Option[Boolean])
case class ErrorMessage(
error : String
)

View File

@ -1,5 +1,6 @@
package code.api.v1_4_0
import code.api.util.APIUtil
import code.api.util.APIUtil.isValidCurrencyISOCode
import code.api.util.ApiRole.{CanCreateCustomer, CanCreateUserCustomerLink}
import code.api.v1_4_0.JSONFactory1_4_0._
@ -10,13 +11,13 @@ import net.liftweb.common.{Box, Full, Loggable}
import net.liftweb.http.js.JE.JsRaw
import net.liftweb.http.{JsonResponse, Req}
import net.liftweb.http.rest.RestHelper
import net.liftweb.json.{Extraction}
import net.liftweb.json.Extraction
import net.liftweb.json.JsonAST.{JField, JObject, JValue}
import net.liftweb.util.Helpers.tryo
import net.liftweb.json.JsonDSL._
import net.liftweb.util.Props
import net.liftweb.json.JsonAST.JValue
import code.api.v1_2_1.AmountOfMoneyJSON
import code.api.v1_2_1.{Akka, AmountOfMoneyJSON}
import code.api.v2_0_0.CreateCustomerJson
import scala.collection.immutable.Nil
@ -657,7 +658,7 @@ trait APIMethods140 extends Loggable with APIMethods130 with APIMethods121{
user =>
val apiDetails: JValue = {
val hostedBy = new HostedBy("Dummy Org", "contact@example.com", "12345")
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, "DUMMY", hostedBy)
val apiInfoJSON = new APIInfoJSON(apiVersion, apiVersionStatus, gitCommit, "DUMMY", hostedBy, Akka(APIUtil.akkaSanityCheck()))
Extraction.decompose(apiInfoJSON)
}

View File

@ -102,7 +102,8 @@ object RemotedataActors extends Loggable {
ActorProps[RemotedataMetricsActor] -> RemotedataMetrics.actorName,
ActorProps[RemotedataTokensActor] -> RemotedataTokens.actorName,
ActorProps[RemotedataNoncesActor] -> RemotedataNonces.actorName,
ActorProps[RemotedataConnectorMetricsActor] -> RemotedataConnectorMetrics.actorName
ActorProps[RemotedataConnectorMetricsActor] -> RemotedataConnectorMetrics.actorName,
ActorProps[RemotedataSanityCheckActor] -> RemotedataSanityCheck.actorName
)
actorsRemotedata.foreach { a => logger.info(actorSystem.actorOf(a._1, name = a._2)) }

View File

@ -0,0 +1,15 @@
package code.remotedata
import akka.pattern.ask
import code.sanitycheck.{RemotedataSanityCheckCaseClasses, SanityChecks}
import net.liftweb.common.Box
object RemotedataSanityCheck extends ActorInit with SanityChecks {
val cc = RemotedataSanityCheckCaseClasses
def remoteAkkaSanityCheck(remoteDataSecret: String): Box[Boolean] =
extractFutureToBox(actor ? cc.remoteAkkaSanityCheck(remoteDataSecret))
}

View File

@ -0,0 +1,26 @@
package code.remotedata
import akka.actor.Actor
import akka.event.Logging
import code.sanitycheck.{RemotedataSanityCheckCaseClasses, SanityChecksImpl}
class RemotedataSanityCheckActor extends Actor with ActorHelper {
val logger = Logging(context.system, this)
val mapper = SanityChecksImpl
val cc = RemotedataSanityCheckCaseClasses
def receive = {
case cc.remoteAkkaSanityCheck(remoteDataSecret: String) =>
logger.debug("remoteAkkaSanityCheck()")
sender ! extractResult(mapper.remoteAkkaSanityCheck(remoteDataSecret))
case message => logger.warning("[AKKA ACTOR ERROR - REQUEST NOT RECOGNIZED] " + message)
}
}

View File

@ -0,0 +1,32 @@
package code.sanitycheck
import code.remotedata.RemotedataSanityCheck
import net.liftweb.common.{Box, Full, Empty}
import net.liftweb.util.{Props, SimpleInjector}
object SanityCheck extends SimpleInjector {
val sanityCheck = new Inject(buildOne _) {}
def buildOne: SanityChecks = RemotedataSanityCheck
}
trait SanityChecks {
def remoteAkkaSanityCheck(remoteDataSecret: String): Box[Boolean]
}
class RemotedataSanityCheckCaseClasses {
case class remoteAkkaSanityCheck(remoteDataSecret: String)
}
object RemotedataSanityCheckCaseClasses extends RemotedataSanityCheckCaseClasses
object SanityChecksImpl extends SanityChecks {
override def remoteAkkaSanityCheck(remoteDataSecret: String): Box[Boolean] = {
Props.get("remotedata.secret") match {
case Full(x) => Full(remoteDataSecret == x)
case _ => Empty
}
}
}