play.api.libs.json.Json Scala Examples

The following examples show how to use play.api.libs.json.Json. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: NaptimeModuleTest.scala    From naptime   with Apache License 2.0 8 votes vote down vote up
package org.coursera.naptime

import java.util.Date
import javax.inject.Inject

import akka.stream.Materializer
import com.google.inject.Guice
import com.google.inject.Stage
import com.linkedin.data.schema.DataSchema
import com.linkedin.data.schema.DataSchemaUtil
import com.linkedin.data.schema.PrimitiveDataSchema
import com.linkedin.data.schema.RecordDataSchema
import org.coursera.naptime.model.KeyFormat
import org.coursera.naptime.resources.TopLevelCollectionResource
import org.coursera.naptime.router2.NaptimeRoutes
import org.junit.Test
import org.mockito.Mockito.mock
import org.scalatest.junit.AssertionsForJUnit
import play.api.libs.json.Json
import play.api.libs.json.OFormat

import scala.concurrent.ExecutionContext

object NaptimeModuleTest {
  case class User(name: String, createdAt: Date)
  object User {
    implicit val oFormat: OFormat[User] = Json.format[User]
  }
  class MyResource(implicit val executionContext: ExecutionContext, val materializer: Materializer)
      extends TopLevelCollectionResource[String, User] {
    override implicit def resourceFormat: OFormat[User] = User.oFormat
    override def keyFormat: KeyFormat[KeyType] = KeyFormat.stringKeyFormat
    override def resourceName: String = "myResource"
    implicit val fields = Fields

    def get(id: String) = Nap.get(ctx => ???)
  }
  object MyFakeModule extends NaptimeModule {
    override def configure(): Unit = {
      bindResource[MyResource]
      bind[MyResource].toInstance(mock(classOf[MyResource]))
      bindSchemaType[Date](DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchema(DataSchema.Type.LONG))
    }
  }

  class OverrideTypesHelper @Inject()(val schemaOverrideTypes: NaptimeModule.SchemaTypeOverrides)
}

class NaptimeModuleTest extends AssertionsForJUnit {
  import NaptimeModuleTest._

  
  @Test
  def checkInferredOverrides(): Unit = {
    val injector = Guice.createInjector(Stage.DEVELOPMENT, MyFakeModule, NaptimeModule)
    val overrides = injector.getInstance(classOf[OverrideTypesHelper])
    assert(overrides.schemaOverrideTypes.size === 1)
    assert(overrides.schemaOverrideTypes.contains("java.util.Date"))
  }

  @Test
  def checkComputedOverrides(): Unit = {
    val injector = Guice.createInjector(Stage.DEVELOPMENT, MyFakeModule, NaptimeModule)
    val overrides = injector.getInstance(classOf[OverrideTypesHelper])
    val routes = injector.getInstance(classOf[NaptimeRoutes])
    assert(1 === routes.routerBuilders.size)
    val routerBuilder = routes.routerBuilders.head
    val inferredSchemaKeyed =
      routerBuilder.types.find(_.key == "org.coursera.naptime.NaptimeModuleTest.User").get
    assert(inferredSchemaKeyed.value.isInstanceOf[RecordDataSchema])
    val userSchema = inferredSchemaKeyed.value.asInstanceOf[RecordDataSchema]
    assert(2 === userSchema.getFields.size())
    val initialCreatedAtSchema = userSchema.getField("createdAt").getType.getDereferencedDataSchema
    assert(initialCreatedAtSchema.isInstanceOf[RecordDataSchema])
    assert(
      initialCreatedAtSchema
        .asInstanceOf[RecordDataSchema]
        .getDoc
        .contains("Unable to infer schema"))
    SchemaUtils.fixupInferredSchemas(userSchema, overrides.schemaOverrideTypes)
    val fixedCreatedAtSchema = userSchema.getField("createdAt").getType.getDereferencedDataSchema
    assert(fixedCreatedAtSchema.isInstanceOf[PrimitiveDataSchema])
  }
} 
Example 2
Source File: PreferencesFrontendService.scala    From pertax-frontend   with Apache License 2.0 6 votes vote down vote up
package services

import com.kenshoo.play.metrics.Metrics
import config.ConfigDecorator
import controllers.auth.requests.UserRequest
import com.google.inject.{Inject, Singleton}
import metrics.HasMetrics
import models.{ActivatePaperlessActivatedResponse, ActivatePaperlessNotAllowedResponse, ActivatePaperlessRequiresUserActionResponse, ActivatePaperlessResponse}
import play.api.Mode.Mode
import play.api.i18n.{I18nSupport, Messages, MessagesApi}
import play.api.libs.json.{JsObject, Json}
import play.api.{Configuration, Environment, Logger}
import uk.gov.hmrc.play.bootstrap.http.DefaultHttpClient
import uk.gov.hmrc.crypto.PlainText
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.play.bootstrap.filters.frontend.crypto.SessionCookieCrypto
import uk.gov.hmrc.play.partials.HeaderCarrierForPartialsConverter
import util.Tools

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class PreferencesFrontendService @Inject()(
  environment: Environment,
  runModeConfiguration: Configuration,
  val simpleHttp: DefaultHttpClient,
  val messagesApi: MessagesApi,
  val metrics: Metrics,
  val configDecorator: ConfigDecorator,
  val sessionCookieCrypto: SessionCookieCrypto,
  val tools: Tools,
  servicesConfig: ServicesConfig)(implicit ec: ExecutionContext)
    extends HeaderCarrierForPartialsConverter with HasMetrics with I18nSupport {

  val mode: Mode = environment.mode
  val preferencesFrontendUrl = servicesConfig.baseUrl("preferences-frontend")

  override def crypto: String => String = cookie => cookie
  def getPaperlessPreference()(implicit request: UserRequest[_]): Future[ActivatePaperlessResponse] = {

    def absoluteUrl = configDecorator.pertaxFrontendHost + request.uri

    def activatePaperless: Future[ActivatePaperlessResponse] =
      withMetricsTimer("get-activate-paperless") { timer =>
        val url =
          s"$preferencesFrontendUrl/paperless/activate?returnUrl=${tools.encryptAndEncode(absoluteUrl)}&returnLinkText=${tools
            .encryptAndEncode(Messages("label.continue"))}" //TODO remove ref to Messages
        simpleHttp.PUT[JsObject, ActivatePaperlessResponse](url, Json.obj("active" -> true)) map {

          case ActivatePaperlessActivatedResponse =>
            timer.completeTimerAndIncrementSuccessCounter()
            ActivatePaperlessActivatedResponse

          case response: ActivatePaperlessRequiresUserActionResponse =>
            timer.completeTimerAndIncrementSuccessCounter()
            response

          case ActivatePaperlessNotAllowedResponse =>
            timer.completeTimerAndIncrementFailedCounter()
            ActivatePaperlessNotAllowedResponse
        } recover {
          case e =>
            timer.completeTimerAndIncrementFailedCounter()
            Logger.warn("Error getting paperless preference record from preferences-frontend-service", e)
            ActivatePaperlessNotAllowedResponse
        }
      }

    if (request.isGovernmentGateway) {
      activatePaperless
    } else {
      Future.successful(ActivatePaperlessNotAllowedResponse)
    }
  }

} 
Example 3
Source File: SessionAuditor.scala    From pertax-frontend   with Apache License 2.0 6 votes vote down vote up
package controllers.auth

import com.google.inject.Inject
import controllers.auth.SessionAuditor._
import controllers.auth.requests.AuthenticatedRequest
import play.api.Logger
import play.api.libs.json.{Format, Json}
import play.api.mvc.Result
import uk.gov.hmrc.auth.core.retrieve.Credentials
import uk.gov.hmrc.auth.core.{ConfidenceLevel, Enrolment}
import uk.gov.hmrc.domain.{Nino, SaUtr}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.audit.http.connector.AuditConnector
import uk.gov.hmrc.play.audit.http.connector.AuditResult.{Failure, Success}
import uk.gov.hmrc.play.audit.model.ExtendedDataEvent
import util.AuditServiceTools

import scala.concurrent.{ExecutionContext, Future}

private[auth] class SessionAuditor @Inject()(auditConnector: AuditConnector)(implicit ec: ExecutionContext)
    extends AuditTags {

  val logger = Logger(this.getClass)

  def auditOnce[A](request: AuthenticatedRequest[A], result: Result)(implicit hc: HeaderCarrier): Future[Result] =
    request.session.get(sessionKey) match {
      case None =>
        logger.info(request.profile.toString)

        val eventDetail = UserSessionAuditEvent(request)

        val sendAuditEvent = auditConnector
          .sendExtendedEvent(
            ExtendedDataEvent(
              auditSource = AuditServiceTools.auditSource,
              auditType = auditType,
              detail = Json.toJson(eventDetail),
              tags = buildTags(request))
          )
          .recover {
            case e: Exception =>
              Logger.warn(s"Unable to audit: ${e.getMessage}")
              Failure("UserSessionAuditor.auditOncePerSession exception occurred whilst auditing", Some(e))
          }

        sendAuditEvent.map {
          case Success => result.addingToSession(sessionKey -> "true")(request)
          case _       => result
        }

      case _ => Future.successful(result)
    }
}

object SessionAuditor {

  val sessionKey = "sessionAudited"
  val auditType = "user-session-visit"

  case class UserSessionAuditEvent(
    nino: Option[Nino],
    credentials: Credentials,
    confidenceLevel: ConfidenceLevel,
    name: Option[String],
    saUtr: Option[SaUtr],
    allEnrolments: Set[Enrolment])

  object UserSessionAuditEvent {

    def apply[A](request: AuthenticatedRequest[A]): UserSessionAuditEvent = {
      val nino = request.nino
      val credentials = request.credentials
      val confidenceLevel = request.confidenceLevel
      val name = request.name map (_.toString)
      val saUtr = request.saEnrolment map (_.saUtr)
      val enrolments = request.enrolments

      UserSessionAuditEvent(nino, credentials, confidenceLevel, name, saUtr, enrolments)
    }

    implicit val credentialsFormats = Json.format[Credentials]
    implicit val formats: Format[UserSessionAuditEvent] = Json.format[UserSessionAuditEvent]
  }

} 
Example 4
Source File: PersonalDetailsControllerSpec.scala    From pertax-frontend   with Apache License 2.0 6 votes vote down vote up
package controllers.address

import config.ConfigDecorator
import controllers.auth.requests.UserRequest
import controllers.auth.{AuthJourney, WithActiveTabAction}
import controllers.controllershelpers.{AddressJourneyCachingHelper, PersonalDetailsCardGenerator}
import models.AddressJourneyTTLModel
import models.dto.AddressPageVisitedDto
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.{times, verify, when}
import org.mockito.Matchers.{eq => meq, _}
import org.scalatestplus.mockito.MockitoSugar
import play.api.http.Status.OK
import play.api.libs.json.Json
import play.api.mvc.{MessagesControllerComponents, Request, Result}
import play.api.test.FakeRequest
import repositories.EditAddressLockRepository
import services.{LocalSessionCache, NinoDisplayService}
import uk.gov.hmrc.http.cache.client.CacheMap
import uk.gov.hmrc.play.audit.http.connector.{AuditConnector, AuditResult}
import uk.gov.hmrc.play.audit.model.DataEvent
import uk.gov.hmrc.renderer.TemplateRenderer
import util.UserRequestFixture.buildUserRequest
import util.{ActionBuilderFixture, BaseSpec, Fixtures, LocalPartialRetriever}
import views.html.interstitial.DisplayAddressInterstitialView
import views.html.personaldetails.{AddressAlreadyUpdatedView, CannotUseServiceView, PersonalDetailsView}

import scala.concurrent.{ExecutionContext, Future}

class PersonalDetailsControllerSpec extends AddressBaseSpec {

  val ninoDisplayService = mock[NinoDisplayService]

  trait LocalSetup extends AddressControllerSetup {

    when(ninoDisplayService.getNino(any(), any())).thenReturn {
      Future.successful(Some(Fixtures.fakeNino))
    }

    def currentRequest[A]: Request[A] = FakeRequest().asInstanceOf[Request[A]]

    def controller =
      new PersonalDetailsController(
        injected[PersonalDetailsCardGenerator],
        mockEditAddressLockRepository,
        ninoDisplayService,
        mockAuthJourney,
        addressJourneyCachingHelper,
        withActiveTabAction,
        mockAuditConnector,
        cc,
        displayAddressInterstitialView,
        injected[PersonalDetailsView]
      ) {}

    "Calling AddressController.onPageLoad" should {

      "call citizenDetailsService.fakePersonDetails and return 200" in new LocalSetup {
        override def sessionCacheResponse: Option[CacheMap] =
          Some(CacheMap("id", Map("addressPageVisitedDto" -> Json.toJson(AddressPageVisitedDto(true)))))

        val result = controller.onPageLoad()(FakeRequest())

        status(result) shouldBe OK
        verify(mockLocalSessionCache, times(1))
          .cache(meq("addressPageVisitedDto"), meq(AddressPageVisitedDto(true)))(any(), any(), any())
        verify(mockEditAddressLockRepository, times(1)).get(any())
      }

      "send an audit event when user arrives on personal details page" in new LocalSetup {
        override def sessionCacheResponse: Option[CacheMap] =
          Some(CacheMap("id", Map("addressPageVisitedDto" -> Json.toJson(AddressPageVisitedDto(true)))))

        val result = controller.onPageLoad()(FakeRequest())
        val eventCaptor = ArgumentCaptor.forClass(classOf[DataEvent])

        status(result) shouldBe OK
        verify(mockAuditConnector, times(1)).sendEvent(eventCaptor.capture())(any(), any())
      }
    }
  }
} 
Example 5
Source File: Components.scala    From gbf-raidfinder   with MIT License 6 votes vote down vote up
package walfie.gbf.raidfinder.server

import akka.actor.ActorSystem
import akka.stream.Materializer
import com.trueaccord.scalapb.json.JsonFormat
import monix.execution.Scheduler
import play.api.BuiltInComponents
import play.api.http.{ContentTypes, DefaultHttpErrorHandler}
import play.api.libs.json.Json
import play.api.Mode.Mode
import play.api.mvc._
import play.api.routing.Router
import play.api.routing.sird._
import play.core.server._
import play.filters.cors.{CORSConfig, CORSFilter}
import play.filters.gzip.GzipFilterComponents
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.Future
import walfie.gbf.raidfinder.protocol.{RaidBossesResponse, BinaryProtobuf}
import walfie.gbf.raidfinder.RaidFinder
import walfie.gbf.raidfinder.server.controller._
import walfie.gbf.raidfinder.server.syntax.ProtocolConverters.RaidBossDomainOps

class Components(
  raidFinder:                 RaidFinder[BinaryProtobuf],
  translator:                 BossNameTranslator,
  port:                       Int,
  mode:                       Mode,
  websocketKeepAliveInterval: FiniteDuration,
  metricsCollector:           MetricsCollector
) extends NettyServerComponents
  with BuiltInComponents with GzipFilterComponents with Controller {

  override lazy val serverConfig = ServerConfig(port = Some(port), mode = mode)

  private val corsFilter = new CORSFilter(corsConfig = CORSConfig().withAnyOriginAllowed)
  override lazy val httpFilters = List(gzipFilter, corsFilter)

  lazy val websocketController = new WebsocketController(
    raidFinder, translator, websocketKeepAliveInterval, metricsCollector
  )(actorSystem, materializer, Scheduler.Implicits.global)

  // The charset isn't necessary, but without it, Chrome displays Japanese incorrectly
  // if you try to view the JSON directly.
  // https://bugs.chromium.org/p/chromium/issues/detail?id=438464
  private val ContentTypeJsonWithUtf8 = "application/json; charset=utf-8"

  lazy val router = Router.from {
    case GET(p"/") =>
      controllers.Assets.at(path = "/public", "index.html")

    case GET(p"/api/bosses.json" ? q_s"name=$names") =>
      val bosses = if (names.nonEmpty) {
        val knownBossesMap = raidFinder.getKnownBosses
        names.collect(knownBossesMap)
      } else raidFinder.getKnownBosses.values

      val responseProtobuf = RaidBossesResponse(
        raidBosses = bosses.map(_.toProtocol(translator)).toSeq
      )
      val responseJson = JsonFormat.toJsonString(responseProtobuf)
      Action(Ok(responseJson).as(ContentTypeJsonWithUtf8))

    case GET(p"/api/metrics.json") =>
      val activeUsers = metricsCollector.getActiveWebSocketCount()
      val json = Json.obj("activeUsers" -> activeUsers)
      Action(Ok(json))

    case GET(p"/ws/raids" ? q_o"keepAlive=${ bool(keepAlive) }") =>
      websocketController.raids(keepAlive = keepAlive.getOrElse(false))

    case GET(p"/$file*") =>
      controllers.Assets.at(path = "/public", file = file)
  }

  override lazy val httpErrorHandler = new ErrorHandler

  override def serverStopHook = () => Future.successful {
    actorSystem.terminate()
  }
} 
Example 6
Source File: TransformerTest.scala    From incubator-s2graph   with Apache License 2.0 6 votes vote down vote up
package org.apache.s2graph.s2jobs.wal

import org.apache.s2graph.s2jobs.task.TaskConf
import org.apache.s2graph.s2jobs.wal.transformer._
import org.scalatest.{FunSuite, Matchers}
import play.api.libs.json.Json

class TransformerTest extends FunSuite with Matchers {
  val walLog = WalLog(1L, "insert", "edge", "a", "b", "s2graph", "friends", """{"name": 1, "url": "www.google.com"}""")

  test("test default transformer") {
    val taskConf = TaskConf.Empty
    val transformer = new DefaultTransformer(taskConf)
    val dimVals = transformer.toDimValLs(walLog, "name", "1")

    dimVals shouldBe Seq(DimVal("friends:name", "1"))
  }

  test("test ExtractDomain from URL") {
    val taskConf = TaskConf.Empty.copy(options =
      Map("urlDimensions" -> Json.toJson(Seq("url")).toString())
    )
    val transformer = new ExtractDomain(taskConf)
    val dimVals = transformer.toDimValLs(walLog, "url", "http://www.google.com/abc")

    dimVals shouldBe Seq(
      DimVal("host", "www.google.com"),
      DimVal("domain", "www.google.com"),
      DimVal("domain", "www.google.com/abc")
    )
  }
} 
Example 7
Source File: InternationalAddressChoiceDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json

case class InternationalAddressChoiceDto(value: Boolean)

object InternationalAddressChoiceDto {

  implicit val formats = Json.format[InternationalAddressChoiceDto]

  val form = Form(
    mapping(
      "internationalAddressChoice" -> optional(boolean)
        .verifying("error.you_must_select_an_answer", _.isDefined)
        .transform[Boolean](_.getOrElse(false), Some(_))
    )(InternationalAddressChoiceDto.apply)(InternationalAddressChoiceDto.unapply)
  )
} 
Example 8
Source File: AddressFinderDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json
import util.PertaxValidators._
case class AddressFinderDto(postcode: String, filter: Option[String])

object AddressFinderDto {

  implicit val formats = Json.format[AddressFinderDto]

  val form = Form(
    mapping(
      "postcode" -> text
        .verifying(
          "error.enter_a_valid_uk_postcode",
          e =>
            e match {
              case PostcodeRegex(_*) => true
              case _                 => false
          }),
      "filter" -> optional(nonEmptyText)
        .verifying("error.enter_valid_characters", e => validateAddressLineCharacters(e))
    )(AddressFinderDto.apply)(AddressFinderDto.unapply)
  )
} 
Example 9
Source File: ClosePostalAddressChoiceDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json

case class ClosePostalAddressChoiceDto(value: Boolean)

object ClosePostalAddressChoiceDto {

  implicit val formats = Json.format[ClosePostalAddressChoiceDto]

  val form = Form(
    mapping(
      "onPageLoad" -> optional(boolean)
        .verifying("error.you_must_select_an_answer", _.isDefined)
        .transform[Boolean](_.getOrElse(false), Some(_))
    )(ClosePostalAddressChoiceDto.apply)(ClosePostalAddressChoiceDto.unapply)
  )
} 
Example 10
Source File: DateDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import org.joda.time.LocalDate
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json
import uk.gov.hmrc.play.mappers.DateTuple._
import play.api.libs.json.JodaWrites._
import play.api.libs.json.JodaReads._

case class DateDto(
  startDate: LocalDate
)

object DateDto {

  implicit val formats = Json.format[DateDto]

  def build(day: Int, month: Int, year: Int) = DateDto(new LocalDate(year, month, day))

  def form(today: LocalDate) = Form(
    mapping(
      "startDate" -> mandatoryDateTuple("error.enter_a_date")
        .verifying("error.date_in_future", !_.isAfter(today))
        .verifying("error.enter_valid_date", !_.isBefore(new LocalDate("1000-01-01")))
    )(DateDto.apply)(DateDto.unapply)
  )
} 
Example 11
Source File: SAWrongCredentialsDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json

final case class SAWrongCredentialsDto(value: Boolean)

object SAWrongCredentialsDto {

  implicit val formats = Json.format[SAWrongCredentialsDto]

  val form = Form(
    mapping(
      "wrongCredentialsFormChoice" -> optional(boolean)
        .verifying("error.you_must_select_an_answer", _.isDefined)
        .transform[Boolean](_.getOrElse(false), Some(_))
    )(SAWrongCredentialsDto.apply)(SAWrongCredentialsDto.unapply)
  )
} 
Example 12
Source File: TaxCreditsChoiceDto.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models.dto

import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json

case class TaxCreditsChoiceDto(value: Boolean)

object TaxCreditsChoiceDto {

  implicit val formats = Json.format[TaxCreditsChoiceDto]

  val form = Form(
    mapping(
      "taxCreditsChoice" -> optional(boolean)
        .verifying("error.you_must_select_an_answer", _.isDefined)
        .transform[Boolean](_.getOrElse(false), Some(_)) //getOrElse here will never fall back to default because of isDefined above
    )(TaxCreditsChoiceDto.apply)(TaxCreditsChoiceDto.unapply)
  )
} 
Example 13
Source File: SelfAssessmentUserType.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models

import play.api.libs.json.{JsDefined, JsError, JsResult, JsString, JsSuccess, JsValue, Json, Reads, Writes}
import uk.gov.hmrc.domain.SaUtr

sealed trait SelfAssessmentUserType

sealed trait SelfAssessmentUser extends SelfAssessmentUserType {
  def saUtr: SaUtr
}

object SelfAssessmentUserType {
  val cacheId = "SelfAssessmentUser"

  val activatedSa = ActivatedOnlineFilerSelfAssessmentUser.toString
  val notActivatedSa = NotYetActivatedOnlineFilerSelfAssessmentUser.toString
  val wrongCredsSa = WrongCredentialsSelfAssessmentUser.toString
  val notEnrolledSa = NotEnrolledSelfAssessmentUser.toString
  val nonFilerSa = NonFilerSelfAssessmentUser.toString

  implicit val writes = new Writes[SelfAssessmentUserType] {
    override def writes(o: SelfAssessmentUserType): JsValue = o match {
      case ActivatedOnlineFilerSelfAssessmentUser(utr) =>
        Json.obj("_type" -> JsString(activatedSa), "utr" -> JsString(utr.toString))
      case NotYetActivatedOnlineFilerSelfAssessmentUser(utr) =>
        Json.obj("_type" -> JsString(notActivatedSa), "utr" -> JsString(utr.toString))
      case WrongCredentialsSelfAssessmentUser(utr) =>
        Json.obj("_type" -> JsString(wrongCredsSa), "utr" -> JsString(utr.toString))
      case NotEnrolledSelfAssessmentUser(utr) =>
        Json.obj("_type" -> JsString(notEnrolledSa), "utr" -> JsString(utr.toString))
      case NonFilerSelfAssessmentUser =>
        Json.obj("_type" -> JsString(nonFilerSa))
    }
  }

  implicit val reads = new Reads[SelfAssessmentUserType] {
    override def reads(json: JsValue): JsResult[SelfAssessmentUserType] =
      (json \ "_type", json \ "utr") match {

        case (JsDefined(JsString(`activatedSa`)), JsDefined(JsString(utr))) =>
          JsSuccess(ActivatedOnlineFilerSelfAssessmentUser(SaUtr(utr)))
        case (JsDefined(JsString(`notActivatedSa`)), JsDefined(JsString(utr))) =>
          JsSuccess(NotYetActivatedOnlineFilerSelfAssessmentUser(SaUtr(utr)))
        case (JsDefined(JsString(`wrongCredsSa`)), JsDefined(JsString(utr))) =>
          JsSuccess(WrongCredentialsSelfAssessmentUser(SaUtr(utr)))
        case (JsDefined(JsString(`notEnrolledSa`)), JsDefined(JsString(utr))) =>
          JsSuccess(NotEnrolledSelfAssessmentUser(SaUtr(utr)))
        case (JsDefined(JsString(`nonFilerSa`)), _) =>
          JsSuccess(NonFilerSelfAssessmentUser)
        case _ => JsError("Could not read SelfAssessmentUserType")
      }
  }
}

case class ActivatedOnlineFilerSelfAssessmentUser(saUtr: SaUtr) extends SelfAssessmentUser
case class NotYetActivatedOnlineFilerSelfAssessmentUser(saUtr: SaUtr) extends SelfAssessmentUser
case class WrongCredentialsSelfAssessmentUser(saUtr: SaUtr) extends SelfAssessmentUser
case class NotEnrolledSelfAssessmentUser(saUtr: SaUtr) extends SelfAssessmentUser
case object NonFilerSelfAssessmentUser extends SelfAssessmentUserType 
Example 14
Source File: TaxCalculation.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package models

import play.api.libs.json.Json

case class TaxCalculation(
  p800_status: String,
  amount: BigDecimal,
  taxYear: Int,
  paymentStatus: Option[String],
  datePaid: Option[String],
  businessReason: Option[String],
  dueDate: Option[String]
)

object TaxCalculation {
  implicit val formats = Json.format[TaxCalculation]
} 
Example 15
Source File: IdentityVerificationFrontendServiceSpec.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package services

import com.codahale.metrics.Timer
import com.kenshoo.play.metrics.Metrics
import org.mockito.Matchers._
import org.mockito.Mockito._
import org.scalatestplus.mockito.MockitoSugar
import play.api.http.Status._
import play.api.libs.json.Json
import play.api.{Configuration, Environment}
import services.http.FakeSimpleHttp
import uk.gov.hmrc.http.HttpResponse
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import util.BaseSpec

class IdentityVerificationFrontendServiceSpec extends BaseSpec {

  trait SpecSetup {
    def httpResponse: HttpResponse
    def simulateIdentityVerificationFrontendIsDown: Boolean

    val anException = new RuntimeException("Any")
    val metricId = "get-iv-journey-status"

    lazy val (service, metrics, timer) = {
      val fakeSimpleHttp = {
        if (simulateIdentityVerificationFrontendIsDown) new FakeSimpleHttp(Right(anException))
        else new FakeSimpleHttp(Left(httpResponse))
      }

      val serviceConfig = app.injector.instanceOf[ServicesConfig]
      val timer = MockitoSugar.mock[Timer.Context]
      val identityVerificationFrontendService: IdentityVerificationFrontendService =
        new IdentityVerificationFrontendService(
          injected[Environment],
          injected[Configuration],
          fakeSimpleHttp,
          MockitoSugar.mock[Metrics],
          serviceConfig) {

          override val metricsOperator: MetricsOperator = MockitoSugar.mock[MetricsOperator]
          when(metricsOperator.startTimer(any())) thenReturn timer
        }

      (identityVerificationFrontendService, identityVerificationFrontendService.metricsOperator, timer)
    }
  }

  "Calling IdentityVerificationFrontend.getIVJourneyStatus" should {

    "return an IdentityVerificationSuccessResponse containing a journey status object when called with a journeyId" in new SpecSetup {
      override lazy val httpResponse = HttpResponse(OK, Some(Json.obj("token" -> "1234", "result" -> "LockedOut")))
      override lazy val simulateIdentityVerificationFrontendIsDown = false

      val r = service.getIVJourneyStatus("1234")

      await(r) shouldBe IdentityVerificationSuccessResponse("LockedOut")
      verify(metrics, times(1)).startTimer(metricId)
      verify(metrics, times(1)).incrementSuccessCounter(metricId)
      verify(timer, times(1)).stop()
    }

    "return IdentityVerificationNotFoundResponse when called with a journeyId that causes a NOT FOUND response" in new SpecSetup {
      override lazy val httpResponse = HttpResponse(NOT_FOUND)
      override lazy val simulateIdentityVerificationFrontendIsDown = false

      val r = service.getIVJourneyStatus("4321")

      await(r) shouldBe IdentityVerificationNotFoundResponse
      verify(metrics, times(1)).startTimer(metricId)
      verify(metrics, times(1)).incrementFailedCounter(metricId)
      verify(timer, times(1)).stop()
    }

    "return TaxCalculationUnexpectedResponse when an unexpected status is returned" in new SpecSetup {
      val seeOtherResponse = HttpResponse(SEE_OTHER)
      override lazy val httpResponse = seeOtherResponse
      override lazy val simulateIdentityVerificationFrontendIsDown = false

      val r = service.getIVJourneyStatus("1234")

      await(r) shouldBe IdentityVerificationUnexpectedResponse(seeOtherResponse)
      verify(metrics, times(1)).startTimer(metricId)
      verify(metrics, times(1)).incrementFailedCounter(metricId)
      verify(timer, times(1)).stop()
    }

    "return IdentityVerificationErrorResponse when called and service is down" in new SpecSetup {
      override lazy val httpResponse = ???
      override lazy val simulateIdentityVerificationFrontendIsDown = true

      val r = service.getIVJourneyStatus("1234")

      await(r) shouldBe IdentityVerificationErrorResponse(anException)
      verify(metrics, times(1)).startTimer(metricId)
      verify(metrics, times(1)).incrementFailedCounter(metricId)
      verify(timer, times(1)).stop()
    }

  }
} 
Example 16
Source File: AddressErrorControllerSpec.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package controllers.address

import controllers.bindable.{PostalAddrType, SoleAddrType}
import models.dto._
import play.api.libs.json.Json
import play.api.mvc._
import play.api.test.FakeRequest
import play.api.test.Helpers._
import uk.gov.hmrc.http.cache.client.CacheMap
import views.html.personaldetails._

class AddressErrorControllerSpec extends AddressBaseSpec {

  trait LocalSetup extends AddressControllerSetup {

    def sessionCacheResponse: Option[CacheMap] =
      Some(CacheMap("id", Map("addressPageVisitedDto" -> Json.toJson(AddressPageVisitedDto(true)))))

    def currentRequest[A]: Request[A] = FakeRequest("POST", "/test").asInstanceOf[Request[A]]

    def controller: AddressErrorController =
      new AddressErrorController(
        mockAuthJourney,
        addressJourneyCachingHelper,
        withActiveTabAction,
        cc,
        displayAddressInterstitialView,
        injected[CannotUseServiceView],
        injected[AddressAlreadyUpdatedView]
      )
  }

  "cannotUseThisService" should {

    "display the cannot use this service page" in new LocalSetup {
      val result = controller.cannotUseThisService(SoleAddrType)(currentRequest)

      status(result) shouldBe OK
      contentAsString(result) should include("You cannot use this service to update your address")
    }
  }

  "showAddressAlreadyUpdated" should {

    "display the showAddressAlreadyUpdated page" in new LocalSetup {

      val result = controller.showAddressAlreadyUpdated(PostalAddrType)(currentRequest)

      status(result) shouldBe OK
      contentAsString(result) should include("Your address has already been updated")
    }
  }
} 
Example 17
Source File: TaxCreditsChoiceControllerSpec.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package controllers.address

import models.dto.AddressPageVisitedDto
import org.mockito.Matchers.any
import org.mockito.Mockito.{times, verify}
import play.api.http.Status.{BAD_REQUEST, OK, SEE_OTHER}
import play.api.libs.json.Json
import play.api.mvc.Request
import play.api.test.FakeRequest
import play.api.test.Helpers._
import uk.gov.hmrc.http.cache.client.CacheMap
import views.html.personaldetails.TaxCreditsChoiceView

class TaxCreditsChoiceControllerSpec extends AddressBaseSpec {

  trait LocalSetup extends AddressControllerSetup {

    def controller: TaxCreditsChoiceController =
      new TaxCreditsChoiceController(
        mockAuthJourney,
        withActiveTabAction,
        cc,
        addressJourneyCachingHelper,
        injected[TaxCreditsChoiceView],
        displayAddressInterstitialView
      )

    def sessionCacheResponse: Option[CacheMap] =
      Some(CacheMap("id", Map("addressPageVisitedDto" -> Json.toJson(AddressPageVisitedDto(true)))))

    def currentRequest[A]: Request[A] = FakeRequest().asInstanceOf[Request[A]]
  }

  "onPageLoad" should {

    "return OK if there is an entry in the cache to say the user previously visited the 'personal details' page" in new LocalSetup {

      val result = controller.onPageLoad(currentRequest)

      status(result) shouldBe OK
      verify(mockLocalSessionCache, times(1)).fetch()(any(), any())
    }

    "redirect back to the start of the journey if there is no entry in the cache to say the user previously visited the 'personal details' page" in new LocalSetup {
      override def sessionCacheResponse: Option[CacheMap] = None

      val result = controller.onPageLoad(currentRequest)

      status(result) shouldBe SEE_OTHER
      redirectLocation(result) shouldBe Some("/personal-account/personal-details")
      verify(mockLocalSessionCache, times(1)).fetch()(any(), any())
    }
  }

  "onSubmit" should {

    "redirect to expected tax credits page when supplied with value = Yes (true)" in new LocalSetup {

      override def currentRequest[A]: Request[A] =
        FakeRequest("POST", "")
          .withFormUrlEncodedBody("taxCreditsChoice" -> "true")
          .asInstanceOf[Request[A]]

      val result =
        controller.onSubmit()(FakeRequest())

      status(result) shouldBe SEE_OTHER
      redirectLocation(result) shouldBe Some("/tax-credits-service/personal/change-address")
    }

    "redirect to ResidencyChoice page when supplied with value = No (false)" in new LocalSetup {

      override def currentRequest[A]: Request[A] =
        FakeRequest("POST", "")
          .withFormUrlEncodedBody("taxCreditsChoice" -> "false")
          .asInstanceOf[Request[A]]

      val result = controller.onSubmit(FakeRequest())

      status(result) shouldBe SEE_OTHER
      redirectLocation(result) shouldBe Some("/personal-account/your-address/residency-choice")
    }

    "return a bad request when supplied no value" in new LocalSetup {

      override def currentRequest[A]: Request[A] =
        FakeRequest("POST", "")
          .asInstanceOf[Request[A]]

      val result = controller.onSubmit(FakeRequest())

      status(result) shouldBe BAD_REQUEST
    }
  }
} 
Example 18
Source File: EnrolmentsConnectorSpec.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package connectors

import models._
import org.joda.time.DateTime
import org.mockito.Matchers.{any, eq => eqTo}
import org.mockito.Mockito.when
import org.scalatest.EitherValues
import org.scalatest.Inspectors.forAll
import org.scalatest.concurrent.ScalaFutures
import org.scalatestplus.mockito.MockitoSugar
import play.api.http.Status._
import play.api.libs.json.{JsObject, JsResultException, Json}
import uk.gov.hmrc.http.{HttpException, HttpResponse}
import uk.gov.hmrc.play.bootstrap.http.DefaultHttpClient
import util.BaseSpec

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

class EnrolmentsConnectorSpec extends BaseSpec with MockitoSugar with ScalaFutures with EitherValues {

  val http = mock[DefaultHttpClient]
  val connector = new EnrolmentsConnector(http, config)
  val baseUrl = config.enrolmentStoreProxyUrl

  "getAssignedEnrolments" should {
    val utr = "1234500000"
    val url = s"$baseUrl/enrolment-store/enrolments/IR-SA~UTR~$utr/users"

    "Return the error message for a BAD_REQUEST response" in {
      when(http.GET[HttpResponse](eqTo(url))(any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(BAD_REQUEST)))

      connector.getUserIdsWithEnrolments(utr).futureValue.left.value should include(BAD_REQUEST.toString)
    }

    "NO_CONTENT response should return no enrolments" in {
      when(http.GET[HttpResponse](eqTo(url))(any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(NO_CONTENT)))

      connector.getUserIdsWithEnrolments(utr).futureValue.right.value shouldBe Seq.empty
    }

    "query users with no principal enrolment returns empty enrolments" in {
      val json = Json.parse("""
                              |{
                              |    "principalUserIds": [],
                              |     "delegatedUserIds": []
                              |}""".stripMargin)

      when(http.GET[HttpResponse](eqTo(url))(any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(OK, Some(json))))

      connector.getUserIdsWithEnrolments(utr).futureValue.right.value shouldBe Seq.empty
    }

    "query users with assigned enrolment return two principleIds" in {
      val json = Json.parse("""
                              |{
                              |    "principalUserIds": [
                              |       "ABCEDEFGI1234567",
                              |       "ABCEDEFGI1234568"
                              |    ],
                              |    "delegatedUserIds": [
                              |     "dont care"
                              |    ]
                              |}""".stripMargin)

      when(http.GET[HttpResponse](eqTo(url))(any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(OK, Some(json))))

      val expected = Seq("ABCEDEFGI1234567", "ABCEDEFGI1234568")

      connector.getUserIdsWithEnrolments(utr).futureValue.right.value shouldBe expected
    }
  }
} 
Example 19
Source File: PayApiConnectorSpec.scala    From pertax-frontend   with Apache License 2.0 5 votes vote down vote up
package connectors

import models.{CreatePayment, PaymentRequest}
import org.mockito.Matchers.{any, eq => eqTo}
import org.mockito.Mockito.when
import org.scalatest.concurrent.ScalaFutures
import org.scalatestplus.mockito.MockitoSugar
import play.api.http.Status._
import play.api.libs.json.{JsResultException, Json}
import uk.gov.hmrc.http.HttpResponse
import uk.gov.hmrc.play.bootstrap.http.DefaultHttpClient
import util.BaseSpec

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

class PayApiConnectorSpec extends BaseSpec with MockitoSugar with ScalaFutures {

  val http = mock[DefaultHttpClient]
  val connector = new PayApiConnector(http, config)
  val paymentRequest = PaymentRequest(config, "some utr")
  val postUrl = config.makeAPaymentUrl

  "createPayment" should {
    "parse the json load for a successful CREATED response" in {
      val json = Json.obj(
        "journeyId" -> "exampleJourneyId",
        "nextUrl"   -> "testNextUrl"
      )

      when(
        http.POST[PaymentRequest, HttpResponse](eqTo(postUrl), eqTo(paymentRequest), any())(any(), any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(CREATED, Some(json))))

      connector.createPayment(paymentRequest).futureValue shouldBe Some(
        CreatePayment("exampleJourneyId", "testNextUrl"))
    }

    "Returns a None when the status code is not CREATED" in {
      when(
        http.POST[PaymentRequest, HttpResponse](eqTo(postUrl), eqTo(paymentRequest), any())(any(), any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(BAD_REQUEST)))

      connector.createPayment(paymentRequest).futureValue shouldBe None
    }

    "Throws a JsResultException when given bad json" in {
      val badJson = Json.obj("abc" -> "invalidData")

      when(
        http.POST[PaymentRequest, HttpResponse](eqTo(postUrl), eqTo(paymentRequest), any())(any(), any(), any(), any()))
        .thenReturn(Future.successful(HttpResponse(CREATED, Some(badJson))))

      val f = connector.createPayment(paymentRequest)
      whenReady(f.failed) { e =>
        e shouldBe a[JsResultException]
      }
    }
  }
} 
Example 20
Source File: Element.scala    From ADReactiveSystem   with GNU General Public License v3.0 5 votes vote down vote up
package com.eevolution.context.dictionary.domain.model

import com.eevolution.context.dictionary.api.{ActiveEnabled, DomainModel, Identifiable, Traceable}
import org.joda.time.DateTime
import play.api.libs.json.{Format, Json}



case class Element(elementId: Int,
                   tenantId: Int,
                   organizationId: Int,
                   isActive: Boolean = true,
                   created: DateTime =  DateTime.now,
                   createdBy: Int,
                   updated: DateTime =  DateTime.now,
                   updatedBy: Int,
                   columnName: String,
                   entityType: String,
                   name: String,
                   printName: Option[String],
                   description: Option[String],
                   help: Option[String],
                   namePO: Option[String],
                   printNamePO: Option[String],
                   descriptionPO : Option[String],
                   helpPO: Option[String],
                   referenceId: Option[Int],
                   fieldLength: Option[Int],
                   referenceValueId: Option[Int],
                   uuid: String
                   ) extends DomainModel
with ActiveEnabled
with Identifiable
with Traceable{
  override type DomainModel = this.type
  override type ActiveEnabled = this.type
  override type Identifiable = this.type
  override type Traceable = this.type
  override def Id: Int = elementId

  override val entityName: String = "AD_Element"
  override val identifier: String = "AD_Element_ID"
}

object Element {
  implicit val format: Format[Element] = Json.format
  def create(elementId: Int,
             tenantId: Int,
             organizationId: Int,
             isActive: Boolean ,
             created: DateTime ,
             createdBy: Int,
             updated: DateTime ,
             updatedBy: Int,
             columnName: String,
             entityType: String,
             name: String,
             printName: String,
             description: String,
             help: String,
             namePO: String,
             printNamePO: String,
             descriptionPO : String,
             helpPO: String,
             referenceId: Int,
             fieldLength: Int,
             referenceValueId: Int,
             uuid: String) = Element(elementId, tenantId, organizationId, isActive , created , createdBy ,
    updated , updatedBy , columnName, entityType, name, None, None, None, None, None, None, None, None, None, None,
    uuid)
} 
Example 21
Source File: IdentitiesArbitrary.scala    From crm-seed   with Apache License 2.0 5 votes vote down vote up
package com.dataengi.crm.identities.arbitraries

import java.util.UUID
import java.util.concurrent.TimeUnit

import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.impl.authenticators.JWTAuthenticator
import com.dataengi.crm.common.arbitraries.CommonArbitrary
import com.dataengi.crm.identities.models.Actions.Action
import com.dataengi.crm.identities.models.InviteStatuses.InviteStatus
import com.dataengi.crm.identities.models._
import com.dataengi.crm.identities.models.PermissionStates.PermissionState
import com.mohiva.play.silhouette.api.util.PasswordInfo
import org.joda.time.DateTime
import org.scalacheck.{Arbitrary, Gen}
import play.api.libs.json.Json

import scala.concurrent.duration.FiniteDuration

trait IdentitiesArbitrary extends CommonArbitrary {

  lazy val companyArbitrary: Arbitrary[Company] = Arbitrary(Gen.resultOf(Company))

  implicit val actionArbitrary: Arbitrary[Action]                   = Arbitrary(Gen.oneOf(Actions.values.toList))
  implicit val permissionStateArbitrary: Arbitrary[PermissionState] = Arbitrary(Gen.oneOf(PermissionStates.values.toList))
  implicit val permissionArbitrary: Arbitrary[Permission]           = Arbitrary(Gen.resultOf(Permission))
  implicit val roleArbitrary: Arbitrary[Role]                       = Arbitrary(Gen.resultOf(Role))
  implicit val inviteStatusArbitrary: Arbitrary[InviteStatus]       = Arbitrary(Gen.oneOf(InviteStatuses.values.toList))
  implicit val uuidArbitrary: Arbitrary[UUID]                       = Arbitrary(Gen.uuid)
  implicit val inviteArbitrary: Arbitrary[Invite]                   = Arbitrary(Gen.resultOf(Invite))

  val dateTimeGen = for {
    value <- Gen.Choose.chooseLong.choose(0, Long.MaxValue)
  } yield new DateTime(value)

  val finiteDurationGen = for {
    value <- Gen.Choose.chooseLong.choose(0, Long.MaxValue)
  } yield new FiniteDuration(value, TimeUnit.NANOSECONDS)

  val jsObject = Gen.oneOf(List(Some(Json.obj("a" -> "b")), None))

  implicit val jsObjectArbitrary       = Arbitrary(jsObject)
  implicit val dateTimeArbitrary       = Arbitrary(dateTimeGen)
  implicit val finiteDurationArbitrary = Arbitrary(finiteDurationGen)
  implicit val loginInfoArbitrary      = Arbitrary(Gen.resultOf(LoginInfo))
  implicit val authenticatorArbitrary  = Arbitrary(Gen.resultOf(JWTAuthenticator.apply _))
  implicit val passwordInfoArbitrary   = Arbitrary(Gen.resultOf(PasswordInfo))
} 
Example 22
Source File: FilterTopFeaturesProcess.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.wal.process

import org.apache.s2graph.s2jobs.task.TaskConf
import org.apache.s2graph.s2jobs.wal.WalLogAgg
import org.apache.s2graph.s2jobs.wal.transformer.{DefaultTransformer, Transformer}
import org.apache.spark.broadcast.Broadcast
import org.apache.spark.sql.functions.{col, udf}
import org.apache.spark.sql.{DataFrame, Dataset, SparkSession}
import play.api.libs.json.{JsObject, Json}

object FilterTopFeaturesProcess {
  private var validFeatureHashKeys: Set[Long] = null
  def getValidFeatureHashKeys(validFeatureHashKeysBCast: Broadcast[Array[Long]]): Set[Long] = {
    if (validFeatureHashKeys == null) {
      validFeatureHashKeys = validFeatureHashKeysBCast.value.toSet
    }

    validFeatureHashKeys
  }

  def collectDistinctFeatureHashes(ss: SparkSession,
                                   filteredDict: DataFrame): Array[Long] = {
    import ss.implicits._

    val featureHashUDF = udf((dim: String, value: String) => WalLogAgg.toFeatureHash(dim, value))

    filteredDict.withColumn("featureHash", featureHashUDF(col("dim"), col("value")))
      .select("featureHash")
      .distinct().as[Long].collect()
  }

  def filterTopKsPerDim(dict: DataFrame,
                        maxRankPerDim: Broadcast[Map[String, Int]],
                        defaultMaxRank: Int): DataFrame = {
    val filterUDF = udf((dim: String, rank: Long) => {
      rank < maxRankPerDim.value.getOrElse(dim, defaultMaxRank)
    })

    dict.filter(filterUDF(col("dim"), col("rank")))
  }

  def filterWalLogAgg(ss: SparkSession,
                      walLogAgg: Dataset[WalLogAgg],
                      transformers: Seq[Transformer],
                      validFeatureHashKeysBCast: Broadcast[Array[Long]]) = {
    import ss.implicits._
    walLogAgg.mapPartitions { iter =>
      val validFeatureHashKeys = getValidFeatureHashKeys(validFeatureHashKeysBCast)

      iter.map { walLogAgg =>
        WalLogAgg.filterProps(walLogAgg, transformers, validFeatureHashKeys)
      }
    }
  }
}

class FilterTopFeaturesProcess(taskConf: TaskConf) extends org.apache.s2graph.s2jobs.task.Process(taskConf) {

  import FilterTopFeaturesProcess._

  
  override def execute(ss: SparkSession, inputMap: Map[String, DataFrame]): DataFrame = {
    import ss.implicits._

    val maxRankPerDim = taskConf.options.get("maxRankPerDim").map { s =>
      Json.parse(s).as[JsObject].fields.map { case (k, jsValue) =>
        k -> jsValue.as[Int]
      }.toMap
    }
    val maxRankPerDimBCast = ss.sparkContext.broadcast(maxRankPerDim.getOrElse(Map.empty))

    val defaultMaxRank = taskConf.options.get("defaultMaxRank").map(_.toInt)

    val featureDict = inputMap(taskConf.options("featureDict"))
    val walLogAgg = inputMap(taskConf.options("walLogAgg")).as[WalLogAgg]

    val transformers = TaskConf.parseTransformers(taskConf)

    val filteredDict = filterTopKsPerDim(featureDict, maxRankPerDimBCast, defaultMaxRank.getOrElse(Int.MaxValue))
    val validFeatureHashKeys = collectDistinctFeatureHashes(ss, filteredDict)
    val validFeatureHashKeysBCast = ss.sparkContext.broadcast(validFeatureHashKeys)

    filterWalLogAgg(ss, walLogAgg, transformers, validFeatureHashKeysBCast).toDF()
  }

  override def mandatoryOptions: Set[String] = Set("featureDict", "walLogAgg")
} 
Example 23
Source File: ExtractServiceName.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.wal.transformer

import org.apache.s2graph.core.JSONParser
import org.apache.s2graph.s2jobs.task.TaskConf
import org.apache.s2graph.s2jobs.wal.{DimVal, WalLog}
import play.api.libs.json.{JsObject, Json}

class ExtractServiceName(taskConf: TaskConf) extends Transformer(taskConf) {
  val serviceDims = Json.parse(taskConf.options.getOrElse("serviceDims", "[]")).as[Set[String]]
  val domainServiceMap = Json.parse(taskConf.options.getOrElse("domainServiceMap", "{}")).as[JsObject].fields.map { case (k, v) =>
      k -> JSONParser.jsValueToString(v)
  }.toMap
  val serviceDimName = taskConf.options.getOrElse("serviceDimName", "serviceDimName")

  override def toDimValLs(walLog: WalLog, propertyKey: String, propertyValue: String): Seq[DimVal] = {
    if (!serviceDims(propertyKey)) Nil
    else {
      val serviceName = domainServiceMap.getOrElse(propertyValue, propertyValue)

      Seq(DimVal(serviceDimName, serviceName))
    }
  }
} 
Example 24
Source File: ExtractDomain.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.wal.transformer

import org.apache.s2graph.s2jobs.task.TaskConf
import org.apache.s2graph.s2jobs.wal.utils.UrlUtils
import org.apache.s2graph.s2jobs.wal.{DimVal, WalLog}
import play.api.libs.json.Json

case class ExtractDomain(taskConf: TaskConf) extends Transformer(taskConf) {
  val urlDimensions = Json.parse(taskConf.options.getOrElse("urlDimensions", "[]")).as[Set[String]]
  val hostDimName = taskConf.options.getOrElse("hostDimName", "host")
  val domainDimName= taskConf.options.getOrElse("domainDimName", "domain")
  val keywordDimName = taskConf.options.getOrElse("keywordDimName", "uri_keywords")
  override def toDimValLs(walLog: WalLog, propertyKey: String, propertyValue: String): Seq[DimVal] = {
    if (!urlDimensions(propertyKey)) Nil
    else {
      val (_, domains, kwdOpt) = UrlUtils.extract(propertyValue)

      domains.headOption.toSeq.map(DimVal(hostDimName, _)) ++
        domains.map(DimVal(domainDimName, _)) ++
        kwdOpt.toSeq.map(DimVal(keywordDimName, _))
    }
  }
} 
Example 25
Source File: JobDescription.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs

import play.api.libs.json.{JsValue, Json}
import org.apache.s2graph.s2jobs.task._
import org.apache.s2graph.s2jobs.udfs.UdfOption

case class JobDescription(
                           name:String,
                           udfs: Seq[UdfOption],
                           sources:Seq[Source],
                           processes:Seq[task.Process],
                           sinks:Seq[Sink]
                         )

object JobDescription extends Logger {
  val dummy = JobDescription("dummy", Nil, Nil, Nil, Nil)

  def apply(jsVal:JsValue):JobDescription = {
    implicit val TaskConfReader = Json.reads[TaskConf]
    implicit val UdfOptionReader = Json.reads[UdfOption]

    logger.debug(s"JobDescription: ${jsVal}")

    val jobName = (jsVal \ "name").as[String]
    val udfs = (jsVal \ "udfs").asOpt[Seq[UdfOption]].getOrElse(Nil)
    val sources = (jsVal \ "source").asOpt[Seq[TaskConf]].getOrElse(Nil).map(conf => getSource(conf))
    val processes = (jsVal \ "process").asOpt[Seq[TaskConf]].getOrElse(Nil).map(conf => getProcess(conf))
    val sinks = (jsVal \ "sink").asOpt[Seq[TaskConf]].getOrElse(Nil).map(conf => getSink(jobName, conf))

    JobDescription(jobName, udfs, sources, processes, sinks)
  }

  def getSource(conf:TaskConf):Source = {
    conf.`type` match {
      case "kafka" => new KafkaSource(conf)
      case "file"  => new FileSource(conf)
      case "hive" => new HiveSource(conf)
      case "jdbc" => new JdbcSource(conf)
      case "s2graph" => new S2GraphSource(conf)
      case _ => throw new IllegalArgumentException(s"unsupported source type : ${conf.`type`}")
    }
  }

  def getProcess(conf:TaskConf): task.Process = {
    conf.`type` match {
      case "sql" => new SqlProcess(conf)
      case "custom" =>
        val customClassOpt = conf.options.get("class")
        customClassOpt match {
          case Some(customClass:String) =>
            logger.debug(s"custom class init.. $customClass")

            Class.forName(customClass)
              .getConstructor(classOf[TaskConf])
              .newInstance(conf)
              .asInstanceOf[task.Process]

          case None => throw new IllegalArgumentException(s"custom class name is not exist.. ${conf}")
        }

      case _ => throw new IllegalArgumentException(s"unsupported process type : ${conf.`type`}")
    }
  }

  def getSink(jobName:String, conf:TaskConf):Sink = {
    conf.`type` match {
      case "kafka" => new KafkaSink(jobName, conf)
      case "file" => new FileSink(jobName, conf)
      case "es" => new ESSink(jobName, conf)
      case "s2graph" => new S2GraphSink(jobName, conf)
      case "jdbc" => new JdbcSink(jobName, conf)
      case "custom" =>
        val customClassOpt = conf.options.get("class")
        customClassOpt match {
          case Some(customClass:String) =>
            logger.debug(s"custom class for sink init.. $customClass")

            Class.forName(customClass)
              .getConstructor(classOf[String], classOf[TaskConf])
              .newInstance(jobName, conf)
              .asInstanceOf[task.Sink]

          case None => throw new IllegalArgumentException(s"sink custom class name is not exist.. ${conf}")
        }
      case _ => throw new IllegalArgumentException(s"unsupported sink type : ${conf.`type`}")
    }

  }
} 
Example 26
Source File: Process.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.task

import org.apache.spark.sql.{DataFrame, SparkSession}
import play.api.libs.json.Json


  private def postProcess(df: DataFrame): DataFrame = {
    import org.apache.spark.sql.functions._

    var resultDF = df

    // watermark
    val timeColumn = conf.options.get(s"time.column")
    logger.debug(s">> timeColumn:  ${timeColumn}")

    val waterMarkDelayTime = conf.options.get(s"watermark.delay.time")
    if (waterMarkDelayTime.isDefined){
      logger.debug(s">> waterMarkDelayTime : ${waterMarkDelayTime}")
      if (timeColumn.isDefined) {
        resultDF = resultDF.withWatermark(timeColumn.get, waterMarkDelayTime.get)
      } else logger.warn("time.column does not exists.. cannot apply watermark")
    }

    // drop duplication
    val dropDuplicateColumns = conf.options.get("drop.duplicate.columns")
    if (dropDuplicateColumns.isDefined) {
      logger.debug(s">> dropDuplicates : ${dropDuplicateColumns}")
      resultDF = resultDF.dropDuplicates(dropDuplicateColumns.get.split(","))
    }

    // groupBy
    val groupedKeysOpt = conf.options.get(s"grouped.keys")
    if (groupedKeysOpt.isDefined) {
      var groupedKeys = groupedKeysOpt.get.split(",").map{ key =>
        col(key.trim)
      }.toSeq

      val windowDurationOpt = conf.options.get(s"grouped.window.duration")
      val slideDurationOpt = conf.options.get(s"grouped.slide.duration")
      if (windowDurationOpt.isDefined && slideDurationOpt.isDefined){
        logger.debug(s">> using window operation : Duration ${windowDurationOpt}, slideDuration : ${slideDurationOpt}")
        groupedKeys = groupedKeys ++ Seq(window(col(timeColumn.get), windowDurationOpt.get, slideDurationOpt.get))
      }
      logger.debug(s">> groupedKeys: ${groupedKeys}")

      // aggregate options
      val aggExprs = Json.parse(conf.options.getOrElse(s"grouped.dataset.agg", "[\"count(1)\"]")).as[Seq[String]].map(expr(_))
      logger.debug(s">> aggr : ${aggExprs}")

      val groupedDF = resultDF.groupBy(groupedKeys: _*)

      resultDF = if (aggExprs.size > 1) {
        groupedDF.agg(aggExprs.head, aggExprs.tail: _*)
      } else {
        groupedDF.agg(aggExprs.head)
      }
    }

    resultDF
  }

} 
Example 27
Source File: Task.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.task

import org.apache.s2graph.core.S2GraphConfigs
import org.apache.s2graph.s2jobs.Logger
import org.apache.s2graph.s2jobs.wal.transformer.Transformer
import play.api.libs.json.Json
//import org.apache.s2graph.s2jobs.loader.GraphFileOptions

object TaskConf {
  val Empty = new TaskConf(name = "empty", `type` = "empty", inputs = Nil, options = Map.empty)

//  def toGraphFileOptions(taskConf: TaskConf): GraphFileOptions = {
//    val args = taskConf.options.filterKeys(GraphFileOptions.OptionKeys)
//      .flatMap(kv => Seq(kv._1, kv._2)).toSeq.toArray
//
//    GraphFileOptions.toOption(args)
//  }

  def parseHBaseConfigs(taskConf: TaskConf): Map[String, Any] = {
    taskConf.options.filterKeys(S2GraphConfigs.HBaseConfigs.DEFAULTS.keySet)
  }

  def parseMetaStoreConfigs(taskConf: TaskConf): Map[String, Any] = {
    taskConf.options.filterKeys(S2GraphConfigs.DBConfigs.DEFAULTS.keySet)
  }

  def parseLocalCacheConfigs(taskConf: TaskConf): Map[String, Any] = {
    taskConf.options.filterKeys(S2GraphConfigs.CacheConfigs.DEFAULTS.keySet).mapValues(_.toInt)
  }

  def parseTransformers(taskConf: TaskConf): Seq[Transformer] = {
    val classes = Json.parse(taskConf.options.getOrElse("transformClasses",
      """["org.apache.s2graph.s2jobs.wal.transformer.DefaultTransformer"]""")).as[Seq[String]]

    classes.map { className =>
      Class.forName(className)
        .getConstructor(classOf[TaskConf])
        .newInstance(taskConf)
        .asInstanceOf[Transformer]
    }
  }
}
case class TaskConf(name:String, `type`:String, inputs:Seq[String] = Nil, options:Map[String, String] = Map.empty, cache:Option[Boolean]=None)

trait Task extends Serializable with Logger {
  val conf: TaskConf
  val LOG_PREFIX = s"[${this.getClass.getSimpleName}]"

  def mandatoryOptions: Set[String]

  def isValidate: Boolean = mandatoryOptions.subsetOf(conf.options.keySet)

  require(isValidate,
    s"""${LOG_PREFIX} not exists mandatory options '${mandatoryOptions.mkString(",")}'
                          in task options (${conf.options.keySet.mkString(",")})
                      """.stripMargin)

  println(s"${LOG_PREFIX} init : $conf")
} 
Example 28
Source File: Grok.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.udfs

import org.apache.s2graph.s2jobs.utils.GrokHelper
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types.{DataType, StructType}
import play.api.libs.json.{JsValue, Json}

class Grok extends Udf {
  import org.apache.spark.sql.functions.udf

  def register(ss: SparkSession, name:String, options:Map[String, String]) = {
    // grok
    val patternDir = options.getOrElse("patternDir", "/tmp")
    val patternFiles = options.getOrElse("patternFiles", "").split(",").toSeq
    val patterns = Json.parse(options.getOrElse("patterns", "{}")).asOpt[Map[String, String]].getOrElse(Map.empty)
    val compilePattern = options("compilePattern")
    val schemaOpt = options.get("schema")

    patternFiles.foreach { patternFile =>
      ss.sparkContext.addFile(s"${patternDir}/${patternFile}")
    }

    implicit val grok = GrokHelper.getGrok(name, patternFiles, patterns, compilePattern)

    val f = if(schemaOpt.isDefined) {
      val schema = DataType.fromJson(schemaOpt.get)
      implicit val keys:Array[String] = schema.asInstanceOf[StructType].fieldNames
      udf(GrokHelper.grokMatchWithSchema _, schema)
    } else {
      udf(GrokHelper.grokMatch _)
    }


    ss.udf.register(name, f)
  }
} 
Example 29
Source File: DegreeKey.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs

import org.apache.s2graph.core._
import org.apache.s2graph.core.storage.SKeyValue
import org.apache.hadoop.hbase.{KeyValue => HKeyValue}
import org.apache.s2graph.core.schema.{Label, LabelMeta}
import org.apache.s2graph.core.types.{InnerValLikeWithTs, SourceVertexId}
import play.api.libs.json.Json


object DegreeKey {
  def fromGraphElement(s2: S2Graph,
                       element: GraphElement,
                       labelMapping: Map[String, String] = Map.empty): Option[DegreeKey] = {
    element match {
      case v: S2Vertex => None
      case e: S2Edge =>
        val newLabel = labelMapping.getOrElse(e.innerLabel.label, e.innerLabel.label)
        val degreeKey = DegreeKey(e.srcVertex.innerIdVal.toString, newLabel, e.getDirection())
        Option(degreeKey)
      case _ => None
    }
  }

  def toEdge(s2: S2Graph, degreeKey: DegreeKey, count: Long): S2EdgeLike = {
    val labelName = degreeKey.labelName
    val direction = degreeKey.direction
    val vertexId = degreeKey.vertexIdStr
    val label = Label.findByName(labelName).getOrElse(throw new RuntimeException(s"$labelName is not found in DB."))
    val dir = GraphUtil.directions(direction)
    val innerVal = JSONParser.jsValueToInnerVal(Json.toJson(vertexId), label.srcColumnWithDir(dir).columnType, label.schemaVersion).getOrElse {
      throw new RuntimeException(s"$vertexId can not be converted into innerval")
    }
    val vertex = s2.elementBuilder.newVertex(SourceVertexId(label.srcColumn, innerVal))

    val ts = System.currentTimeMillis()
    val propsWithTs = Map(LabelMeta.timestamp -> InnerValLikeWithTs.withLong(ts, ts, label.schemaVersion),
      LabelMeta.degree -> InnerValLikeWithTs.withLong(count, ts, label.schemaVersion))

    s2.elementBuilder.newEdge(vertex, vertex, label, dir, propsWithTs = propsWithTs)
  }

  def toSKeyValue(s2: S2Graph,
                  degreeKey: DegreeKey,
                  count: Long): Seq[SKeyValue] = {
    try {
      val edge = toEdge(s2, degreeKey, count)
      edge.edgesWithIndex.flatMap { indexEdge =>
        s2.getStorage(indexEdge.label).serDe.indexEdgeSerializer(indexEdge).toKeyValues
      }
    } catch {
      case e: Exception => Nil
    }
  }

  def toKeyValue(s2: S2Graph, degreeKey: DegreeKey, count: Long): Seq[HKeyValue] = {
    toSKeyValue(s2, degreeKey, count).map(skv => new HKeyValue(skv.row, skv.cf, skv.qualifier, skv.timestamp, skv.value))
  }
}

case class DegreeKey(vertexIdStr: String, labelName: String, direction: String) 
Example 30
Source File: JobLauncher.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs

import org.apache.s2graph.s2jobs.udfs.Udf
import org.apache.spark.sql.SparkSession
import play.api.libs.json.{JsValue, Json}

import scala.io.Source

case class JobOption(
                      name:String = "S2BatchJob",
                      confType:String = "db",
                      jobId:Int = -1,
                      confFile:String = ""
                    )

object JobLauncher extends Logger {

  def parseArguments(args: Array[String]): JobOption = {
    val parser = new scopt.OptionParser[JobOption]("run") {
      opt[String]('n', "name").required().action((x, c) =>
        c.copy(name = x)).text("job display name")

      cmd("file").action((_, c) => c.copy(confType = "file"))
        .text("get config from file")
        .children(
          opt[String]('f', "confFile").required().valueName("<file>").action((x, c) =>
            c.copy(confFile = x)).text("configuration file")
        )

      cmd("db").action((_, c) => c.copy(confType = "db"))
        .text("get config from db")
        .children(
          opt[String]('i', "jobId").required().valueName("<jobId>").action((x, c) =>
            c.copy(jobId = x.toInt)).text("configuration file")
        )
    }

    parser.parse(args, JobOption()) match {
      case Some(o) => o
      case None =>
        parser.showUsage()
        throw new IllegalArgumentException(s"failed to parse options... (${args.mkString(",")}")
    }
  }

  def getConfig(options: JobOption):JsValue = options.confType match {
    case "file" =>
      Json.parse(Source.fromFile(options.confFile).mkString)
    case "db" =>
      throw new IllegalArgumentException(s"'db' option that read config file from database is not supported yet.. ")
  }

  def main(args: Array[String]): Unit = {

    val options = parseArguments(args)
    logger.info(s"Job Options : ${options}")

    val jobDescription = JobDescription(getConfig(options))

    val ss = SparkSession
      .builder()
      .appName(s"${jobDescription.name}")
      .config("spark.driver.maxResultSize", "20g")
      .enableHiveSupport()
      .getOrCreate()

    // register udfs
    jobDescription.udfs.foreach{ udfOption =>
      val udf = Class.forName(udfOption.`class`).newInstance().asInstanceOf[Udf]
      logger.info((s"[udf register] ${udfOption}"))
      udf.register(ss, udfOption.name, udfOption.params.getOrElse(Map.empty))
    }

    val job = new Job(ss, jobDescription)
    job.run()
  }
} 
Example 31
Source File: S2StreamQueryWriter.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.spark.sql.streaming

import com.typesafe.config.ConfigFactory
import org.apache.s2graph.core.{GraphElement, JSONParser}
import org.apache.s2graph.s2jobs.S2GraphHelper
import org.apache.s2graph.spark.sql.streaming.S2SinkConfigs._
import org.apache.spark.TaskContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.catalyst.InternalRow
import org.apache.spark.sql.catalyst.encoders.{ExpressionEncoder, RowEncoder}
import org.apache.spark.sql.types.StructType
import play.api.libs.json.{JsObject, Json}

import scala.collection.mutable.ListBuffer
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.util.Try

private [sql] class S2StreamQueryWriter(
                                         serializedConf:String,
                                         schema: StructType ,
                                         commitProtocol: S2CommitProtocol
                                       ) extends Serializable with Logger {
  private val config = ConfigFactory.parseString(serializedConf)
  private val s2Graph = S2GraphHelper.getS2Graph(config)
  private val encoder: ExpressionEncoder[Row] = RowEncoder(schema).resolveAndBind()
  private val RESERVED_COLUMN = Set("timestamp", "from", "to", "label", "operation", "elem", "direction")


  def run(taskContext: TaskContext, iters: Iterator[InternalRow]): TaskCommit = {
    val taskId = s"stage-${taskContext.stageId()}, partition-${taskContext.partitionId()}, attempt-${taskContext.taskAttemptId()}"
    val partitionId= taskContext.partitionId()

    val groupedSize = getConfigString(config, S2_SINK_GROUPED_SIZE, DEFAULT_GROUPED_SIZE).toInt
    val waitTime = getConfigString(config, S2_SINK_WAIT_TIME, DEFAULT_WAIT_TIME_SECONDS).toInt

    commitProtocol.initTask()
    try {
      var list = new ListBuffer[(String, Int)]()
      val rst = iters.flatMap(rowToEdge).grouped(groupedSize).flatMap{ elements =>
        logger.debug(s"[$taskId][elements] ${elements.size} (${elements.map(e => e.toLogString).mkString(",\n")})")
        elements.groupBy(_.serviceName).foreach{ case (service, elems) =>
          list += ((service, elems.size))
        }

        val mutateF = s2Graph.mutateElements(elements, true)
        Await.result(mutateF, Duration(waitTime, "seconds"))
      }

      val (success, fail) = rst.toSeq.partition(r => r.isSuccess)
      val counter = list.groupBy(_._1).map{ case (service, t) =>
        val sum = t.toList.map(_._2).sum
        (service, sum)
      }
      logger.info(s"[$taskId] success : ${success.size}, fail : ${fail.size} ($counter)")


      commitProtocol.commitTask(TaskState(partitionId, success.size, fail.size, counter))

    } catch {
      case t: Throwable =>
        commitProtocol.abortTask(TaskState(partitionId))
        throw t
    }
  }

  private def rowToEdge(internalRow:InternalRow): Option[GraphElement] =
    S2GraphHelper.sparkSqlRowToGraphElement(s2Graph, encoder.fromRow(internalRow), schema, RESERVED_COLUMN)
} 
Example 32
Source File: TaskConfTest.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.s2jobs.task

import org.apache.s2graph.s2jobs.BaseSparkTest
import play.api.libs.json.Json

class TaskConfTest extends BaseSparkTest {
  test("parse dump loader TaskConf") {
    val s =
      """
        |{
        |        "name": "s2graph_sink",
        |        "inputs": [
        |          "filter"
        |        ],
        |        "type": "s2graph",
        |        "options": {
        |          "writeMethod": "bulk",
        |          "hbase.zookeeper.quorum": "localhost",
        |          "db.default.driver": "com.mysql.jdbc.Driver",
        |          "db.default.url": "jdbc:mysql://localhost:3306/graph_dev",
        |          "db.default.user": "graph",
        |          "db.default.password": "graph",
        |          "--input": "dummy",
        |          "--tempDir": "dummy",
        |          "--output": "/tmp/HTableMigrate",
        |          "--zkQuorum": "localhost",
        |          "--table": "CopyRated",
        |          "--dbUrl": "jdbc:mysql://localhost:3306/graph_dev",
        |          "--dbUser": "graph",
        |          "--dbPassword": "graph",
        |          "--dbDriver": "com.mysql.jdbc.Driver",
        |          "--autoEdgeCreate": "true",
        |          "--buildDegree": "true"
        |        }
        |      }
      """.stripMargin

    implicit val TaskConfReader = Json.reads[TaskConf]
    val taskConf = Json.parse(s).as[TaskConf]

  }
} 
Example 33
Source File: S2VertexProperty.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.core

import java.util

import org.apache.s2graph.core.schema.ColumnMeta
import org.apache.s2graph.core.types.{CanInnerValLike, InnerValLike}
import org.apache.tinkerpop.gremlin.structure.{Property, VertexProperty}
import play.api.libs.json.Json

object S2VertexPropertyId {
  def fromString(s: String): S2VertexPropertyId = {
    io.Conversions.s2VertexPropertyIdReads.reads(Json.parse(s)).get
  }
}
case class S2VertexPropertyId(columnMeta: ColumnMeta, value: InnerValLike) {
  override def toString: String = {
    io.Conversions.s2VertexPropertyIdWrites.writes(this).toString()
  }
}

case class S2VertexProperty[V](element: S2VertexLike,
                               columnMeta: ColumnMeta,
                               key: String,
                               v: V) extends VertexProperty[V] {
  import CanInnerValLike._
  implicit lazy val encodingVer = element.serviceColumn.schemaVersion
  lazy val innerVal = CanInnerValLike.anyToInnerValLike.toInnerVal(value)
  def toBytes: Array[Byte] = {
    innerVal.bytes
  }


  val valueAny = castValue(v, columnMeta.dataType)

  val value = castValue(v, columnMeta.dataType).asInstanceOf[V]

  override def properties[U](strings: String*): util.Iterator[Property[U]] = ???

  override def property[A](key: String, value: A): Property[A] = ???

  override def remove(): Unit = {
    if (!element.graph.features.vertex.properties.supportsRemoveProperty) {
      throw Property.Exceptions.propertyRemovalNotSupported
    }
    isRemoved = true
  }

  override def id(): AnyRef = S2VertexPropertyId(columnMeta, innerVal)

  @volatile var isRemoved = false

  override def isPresent: Boolean = !isRemoved

  override def hashCode(): Int = {
    (element, id()).hashCode()
  }

  override def equals(other: Any): Boolean = other match {
    case p: VertexProperty[_] => element == p.element && id() == p.id()
    case _ => false
  }

  override def toString(): String = {
//    Map("columnMeta" -> columnMeta.toString, "key" -> key, "value" -> value).toString
    s"vp[${key}->${value}]"
  }
} 
Example 34
Source File: InceptionFetcherTest.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.core.fetcher.tensorflow

import java.io.File

import org.apache.commons.io.FileUtils
import org.apache.s2graph.core.fetcher.BaseFetcherTest
import play.api.libs.json.Json

class InceptionFetcherTest extends BaseFetcherTest {
  val runDownloadModel: Boolean = true
  val runCleanup: Boolean = true

  def cleanup(downloadPath: String, dir: String) = {
    synchronized {
      FileUtils.deleteQuietly(new File(downloadPath))
      FileUtils.deleteDirectory(new File(dir))
    }
  }
  def downloadModel(dir: String) = {
    import sys.process._
    synchronized {
      FileUtils.forceMkdir(new File(dir))

      val url = "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip"
      val wget = s"wget $url"
      wget !
      val unzip = s"unzip inception5h.zip -d $dir"
      unzip !
    }
  }

  //TODO: make this test case to run smoothly
  ignore("test get bytes for image url") {
    val downloadPath = "inception5h.zip"
    val modelPath = "inception"
    try {
      if (runDownloadModel) downloadModel(modelPath)

      val serviceName = "s2graph"
      val columnName = "user"
      val labelName = "image_net"
      val options =
        s"""
           |{
           |  "fetcher": {
           |    "className": "org.apache.s2graph.core.fetcher.tensorflow.InceptionFetcher",
           |    "modelPath": "$modelPath"
           |  }
           |}
       """.stripMargin
      val (service, column, label) = initEdgeFetcher(serviceName, columnName, labelName, Option(options))

      val srcVertices = Seq(
        "http://www.gstatic.com/webp/gallery/1.jpg",
        "http://www.gstatic.com/webp/gallery/2.jpg",
        "http://www.gstatic.com/webp/gallery/3.jpg"
      )
      val stepResult = queryEdgeFetcher(service, column, label, srcVertices)

      stepResult.edgeWithScores.groupBy(_.edge.srcVertex).foreach { case (srcVertex, ls) =>
        val url = srcVertex.innerIdVal.toString
        val scores = ls.map { es =>
          val edge = es.edge
          val label = edge.tgtVertex.innerIdVal.toString
          val score = edge.property[Double]("score").value()

          Json.obj("label" -> label, "score" -> score)
        }
        val jsArr = Json.toJson(scores)
        val json = Json.obj("url" -> url, "scores" -> jsArr)
        println(Json.prettyPrint(json))
      }
    } finally {
      if (runCleanup) cleanup(downloadPath, modelPath)
    }
  }
} 
Example 35
Source File: TrxLog.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.counter

import play.api.libs.json.Json

// item1 -> likedCount -> month:2015-10, 1
// edge
  // policyId = Label.findByName(likedCount).id.get
  // item = edge.srcVertexId
  // results =
case class TrxLog(success: Boolean, policyId: Int, item: String, results: Iterable[TrxLogResult])

// interval = m, ts = 2015-10, "age.gender.20.M", 1, 2
case class TrxLogResult(interval: String, ts: Long, dimension: String, value: Long, result: Long = -1)

object TrxLogResult {
  implicit val writes = Json.writes[TrxLogResult]
  implicit val reads = Json.reads[TrxLogResult]
  implicit val formats = Json.format[TrxLogResult]
}

object TrxLog {
  implicit val writes = Json.writes[TrxLog]
  implicit val reads = Json.reads[TrxLog]
  implicit val formats = Json.format[TrxLog]
} 
Example 36
Source File: GraphOperation.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.counter.core.v2

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import com.typesafe.config.Config
import org.apache.http.HttpStatus
import org.apache.s2graph.counter.config.S2CounterConfig
import org.apache.s2graph.counter.core.v2.ExactStorageGraph._
import org.asynchttpclient.DefaultAsyncHttpClientConfig
import org.slf4j.LoggerFactory
import play.api.libs.json.{JsObject, JsValue, Json}
import scala.concurrent.Await
import scala.concurrent.duration._

class GraphOperation(config: Config) {
  // using play-ws without play app
  implicit val materializer = ActorMaterializer.create(ActorSystem(getClass.getSimpleName))
  private val builder = new DefaultAsyncHttpClientConfig.Builder()
  private val wsClient = new play.api.libs.ws.ning.NingWSClient(builder.build)
  private val s2config = new S2CounterConfig(config)
  val s2graphUrl = s2config.GRAPH_URL
  private[counter] val log = LoggerFactory.getLogger(this.getClass)

  import scala.concurrent.ExecutionContext.Implicits.global

  def createLabel(json: JsValue): Boolean = {
    // fix counter label's schemaVersion
    val newJson = json.as[JsObject] ++ Json.obj("schemaVersion" -> "v2")
    val future = wsClient.url(s"$s2graphUrl/graphs/createLabel").post(newJson).map { resp =>
      resp.status match {
        case HttpStatus.SC_OK =>
          true
        case _ =>
          throw new RuntimeException(s"failed createLabel. errCode: ${resp.status} body: ${resp.body} query: $json")
      }
    }

    Await.result(future, 10 second)
  }

  def deleteLabel(label: String): Boolean = {
    val future = wsClient.url(s"$s2graphUrl/graphs/deleteLabel/$label").put("").map { resp =>
      resp.status match {
        case HttpStatus.SC_OK =>
          true
        case _ =>
          throw new RuntimeException(s"failed deleteLabel. errCode: ${resp.status} body: ${resp.body}")
      }
    }

    Await.result(future, 10 second)
  }
} 
Example 37
Source File: RankCounterItem.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.rest.play.models

import play.api.libs.json.{Json, Writes}


case class RankCounterItem(rank: Int, id: String, score: Double)

case class RankCounterDimensionItem(interval: String, ts: Long, dimension: String, total: Double, ranks: Seq[RankCounterItem])

case class RankCounterResultMeta(service: String, action: String)

case class RankCounterResult(meta: RankCounterResultMeta, data: Seq[RankCounterDimensionItem])

object RankCounterItem {
  implicit val format = Json.format[RankCounterItem]
}

object RankCounterDimensionItem {
  implicit val writes = new Writes[RankCounterDimensionItem] {
    def writes(item: RankCounterDimensionItem) = Json.obj(
      "interval" -> item.interval,
      "ts" -> item.ts,
      "time" -> tsFormat.format(item.ts),
      "dimension" -> item.dimension,
      "total" -> item.total,
      "ranks" -> item.ranks
    )
  }
  implicit val reads = Json.reads[RankCounterDimensionItem]
}

object RankCounterResultMeta {
  implicit val format = Json.format[RankCounterResultMeta]
}

object RankCounterResult {
  implicit val format = Json.format[RankCounterResult]
} 
Example 38
Source File: ExactCounterItem.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.rest.play.models

import play.api.libs.json.{Json, Writes}


case class ExactCounterItem(ts: Long, count: Long, score: Double)

case class ExactCounterIntervalItem(interval: String, dimension: Map[String, String], counter: Seq[ExactCounterItem])

case class ExactCounterResultMeta(service: String, action: String, item: String)

case class ExactCounterResult(meta: ExactCounterResultMeta, data: Seq[ExactCounterIntervalItem])

object ExactCounterItem {
  implicit val writes = new Writes[ExactCounterItem] {
    def writes(item: ExactCounterItem) = Json.obj(
      "ts" -> item.ts,
      "time" -> tsFormat.format(item.ts),
      "count" -> item.count,
      "score" -> item.score
    )
  }
  implicit val reads = Json.reads[ExactCounterItem]
}

object ExactCounterIntervalItem {
  implicit val format = Json.format[ExactCounterIntervalItem]
}

object ExactCounterResultMeta {
  implicit val format = Json.format[ExactCounterResultMeta]
}

object ExactCounterResult {
  implicit val formats = Json.format[ExactCounterResult]
} 
Example 39
Source File: JsonBodyParser.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.rest.play.controllers

import akka.util.ByteString
import org.apache.s2graph.core.utils.logger
import play.api.Play
import play.api.libs.iteratee.Iteratee
import play.api.libs.json.{JsValue, Json}
import play.api.libs.streams.Streams
import play.api.mvc._

import scala.concurrent.Future
import scala.util.control.NonFatal

object s2parse extends BodyParsers {

  import parse._

  val defaultMaxTextLength = 1024 * 512
  val defaultMaxJsonLength = 1024 * 512

  def json: BodyParser[JsValue] = json(defaultMaxTextLength)

  
  def jsonText: BodyParser[String] = when(
    _.contentType.exists(m => m.equalsIgnoreCase("text/json") || m.equalsIgnoreCase("application/json")),
    jsonText(defaultMaxTextLength),
    createBadResult("Expecting text/json or application/json body")
  )

  private def jsonText(maxLength: Int): BodyParser[String] = BodyParser("json, maxLength=" + maxLength) { request =>
    import play.api.libs.iteratee.Execution.Implicits.trampoline
    import play.api.libs.iteratee.Traversable

    val iteratee = Traversable.takeUpTo[ByteString](maxLength)
      .transform(Iteratee.consume[ByteString]().map(_.utf8String))
      .flatMap(Iteratee.eofOrElse(Results.EntityTooLarge))

    Streams.iterateeToAccumulator(iteratee)
  }

  def json(maxLength: Int): BodyParser[JsValue] = when(
    _.contentType.exists(m => m.equalsIgnoreCase("text/json") || m.equalsIgnoreCase("application/json")),
    tolerantJson(maxLength),
    createBadResult("Expecting text/json or application/json body")
  )

  def tolerantJson(maxLength: Int): BodyParser[JsValue] =
    tolerantBodyParser[JsValue]("json", maxLength, "Invalid Json") { (request, bytes) =>
      // Encoding notes: RFC 4627 requires that JSON be encoded in Unicode, and states that whether that's
      // UTF-8, UTF-16 or UTF-32 can be auto detected by reading the first two bytes. So we ignore the declared
      // charset and don't decode, we passing the byte array as is because Jackson supports auto detection.
      Json.parse(bytes)
    }

  private def tolerantBodyParser[A](name: String, maxLength: Int, errorMessage: String)(parser: (RequestHeader, Array[Byte]) => A): BodyParser[A] =
    BodyParser(name + ", maxLength=" + maxLength) { request =>
      import play.api.libs.iteratee.Execution.Implicits.trampoline
      import play.api.libs.iteratee.Traversable

      import scala.util.control.Exception._

      val bodyParser: Iteratee[ByteString, Either[Result, Either[Future[Result], A]]] =
        Traversable.takeUpTo[ByteString](maxLength).transform(
          Iteratee.consume[ByteString]().map { bytes =>
            allCatch[A].either {
              parser(request, bytes.toByteBuffer.array())
            }.left.map {
              case NonFatal(e) =>
                val txt = bytes.utf8String
                logger.error(s"$errorMessage: $txt", e)
                createBadResult(s"$errorMessage: $e")(request)
              case t => throw t
            }
          }
        ).flatMap(Iteratee.eofOrElse(Results.EntityTooLarge))

      Streams.iterateeToAccumulator(bodyParser).mapFuture {
        case Left(tooLarge) => Future.successful(Left(tooLarge))
        case Right(Left(badResult)) => badResult.map(Left.apply)
        case Right(Right(body)) => Future.successful(Right(body))
      }
    }

  private def createBadResult(msg: String): RequestHeader => Future[Result] = { request =>
    Play.maybeApplication.map(_.global.onBadRequest(request, msg))
      .getOrElse(Future.successful(Results.BadRequest))
  }
} 
Example 40
Source File: VertexController.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.rest.play.controllers

import org.apache.s2graph.core.rest.RequestParser
import org.apache.s2graph.core.storage.MutateResponse
import org.apache.s2graph.core.utils.logger
import org.apache.s2graph.core.{ExceptionHandler, GraphExceptions, S2Graph}
import org.apache.s2graph.rest.play.actors.QueueActor
import org.apache.s2graph.rest.play.config.Config
import play.api.libs.json.{JsValue, Json}
import play.api.mvc.{Controller, Result}

import scala.concurrent.Future

object VertexController extends Controller {
  private val s2: S2Graph = org.apache.s2graph.rest.play.Global.s2graph
  private val requestParser: RequestParser = org.apache.s2graph.rest.play.Global.s2parser
  private val walLogHandler: ExceptionHandler = org.apache.s2graph.rest.play.Global.wallLogHandler

  import ApplicationController._
  import ExceptionHandler._
  import play.api.libs.concurrent.Execution.Implicits._

  def tryMutates(jsValue: JsValue, operation: String, serviceNameOpt: Option[String] = None, columnNameOpt: Option[String] = None, withWait: Boolean = false): Future[Result] = {
    if (!Config.IS_WRITE_SERVER) Future.successful(Unauthorized)
    else {
      try {
        val vertices = requestParser.toVertices(jsValue, operation, serviceNameOpt, columnNameOpt)

        for (vertex <- vertices) {
          val kafkaTopic = toKafkaTopic(vertex.isAsync)
          walLogHandler.enqueue(toKafkaMessage(kafkaTopic, vertex, None))
        }

        //FIXME:
        val verticesToStore = vertices.filterNot(v => skipElement(v.isAsync))
        if (verticesToStore.isEmpty) Future.successful(jsonResponse(Json.toJson(Seq.empty[Boolean])))
        else {
          if (withWait) {
            val rets = s2.mutateVertices(verticesToStore, withWait = true).map(_.map(_.isSuccess))
            rets.map(Json.toJson(_)).map(jsonResponse(_))
          } else {
            val rets = verticesToStore.map { vertex => QueueActor.router ! vertex; true }
            Future.successful(jsonResponse(Json.toJson(rets)))
          }
        }
      } catch {
        case e: GraphExceptions.JsonParseException => Future.successful(BadRequest(s"e"))
        case e: Exception =>
          logger.error(s"[Failed] tryMutates", e)
          Future.successful(InternalServerError(s"${e.getStackTrace}"))
      }
    }
  }

  def inserts() = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "insert")
  }

  def insertsWithWait() = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "insert", withWait = true)
  }

  def insertsSimple(serviceName: String, columnName: String) = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "insert", Some(serviceName), Some(columnName))
  }

  def deletes() = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "delete")
  }

  def deletesWithWait() = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "delete", withWait = true)
  }

  def deletesSimple(serviceName: String, columnName: String) = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "delete", Some(serviceName), Some(columnName))
  }

  def deletesAll() = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "deleteAll")
  }

  def deletesAllSimple(serviceName: String, columnName: String) = withHeaderAsync(jsonParser) { request =>
    tryMutates(request.body, "deleteAll", Some(serviceName), Some(columnName))
  }

} 
Example 41
Source File: S2GraphMutateRoute.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ExceptionHandler, Route}
import com.fasterxml.jackson.core.JsonParseException
import org.apache.s2graph.core.rest.RequestParser
import org.apache.s2graph.core.storage.MutateResponse
import org.apache.s2graph.core.{GraphElement, S2Graph}
import org.slf4j.LoggerFactory
import play.api.libs.json.{JsValue, Json}

import scala.concurrent.{ExecutionContext, Future}

trait S2GraphMutateRoute extends PlayJsonSupport {

  val s2graph: S2Graph
  val logger = LoggerFactory.getLogger(this.getClass)

  lazy val parser = new RequestParser(s2graph)

  lazy val exceptionHandler = ExceptionHandler {
    case ex: JsonParseException => complete(StatusCodes.BadRequest -> ex.getMessage)
    case ex: java.lang.IllegalArgumentException => complete(StatusCodes.BadRequest -> ex.getMessage)
  }

  lazy val mutateVertex = path("vertex" / Segments) { params =>
    implicit val ec = s2graph.ec

    val (operation, serviceNameOpt, columnNameOpt) = params match {
      case operation :: serviceName :: columnName :: Nil => (operation, Option(serviceName), Option(columnName))
      case operation :: Nil => (operation, None, None)
      case _ => throw new RuntimeException("invalid params")
    }

    entity(as[JsValue]) { payload =>
      val future = vertexMutate(payload, operation, serviceNameOpt, columnNameOpt).map(Json.toJson(_))

      complete(future)
    }
  }

  lazy val mutateEdge = path("edge" / Segment) { operation =>
    implicit val ec = s2graph.ec

    entity(as[JsValue]) { payload =>
      val future = edgeMutate(payload, operation, withWait = true).map(Json.toJson(_))

      complete(future)
    }
  }

  def vertexMutate(jsValue: JsValue,
                   operation: String,
                   serviceNameOpt: Option[String] = None,
                   columnNameOpt: Option[String] = None,
                   withWait: Boolean = true)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val vertices = parser.toVertices(jsValue, operation, serviceNameOpt, columnNameOpt)

    val verticesToStore = vertices.filterNot(_.isAsync)

    s2graph.mutateVertices(verticesToStore, withWait).map(_.map(_.isSuccess))
  }

  def edgeMutate(elementsWithTsv: Seq[(GraphElement, String)], withWait: Boolean)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val elementWithIdxs = elementsWithTsv.zipWithIndex
    val (elementSync, elementAsync) = elementWithIdxs.partition { case ((element, tsv), idx) => !element.isAsync }

    val retToSkip = elementAsync.map(_._2 -> MutateResponse.Success)
    val (elementsToStore, _) = elementSync.map(_._1).unzip
    val elementsIdxToStore = elementSync.map(_._2)

    s2graph.mutateElements(elementsToStore, withWait).map { mutateResponses =>
      elementsIdxToStore.zip(mutateResponses) ++ retToSkip
    }.map(_.sortBy(_._1).map(_._2.isSuccess))
  }

  def edgeMutate(jsValue: JsValue, operation: String, withWait: Boolean)(implicit ec: ExecutionContext): Future[Seq[Boolean]] = {
    val edgesWithTsv = parser.parseJsonFormat(jsValue, operation)
    edgeMutate(edgesWithTsv, withWait)
  }

  // expose routes
  lazy val mutateRoute: Route =
    post {
      concat(
        handleExceptions(exceptionHandler) {
          mutateVertex
        },
        handleExceptions(exceptionHandler) {
          mutateEdge
        }
      )
    }

} 
Example 42
Source File: MutateRouteSpec.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model._
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.typesafe.config.ConfigFactory
import org.apache.s2graph.core.Management.JsonModel.Prop
import org.apache.s2graph.core.S2Graph
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}
import org.slf4j.LoggerFactory
import play.api.libs.json.{JsValue, Json}

class MutateRouteSpec extends WordSpec with Matchers with PlayJsonSupport with ScalaFutures with ScalatestRouteTest with S2GraphMutateRoute with BeforeAndAfterAll {

  import scala.collection.JavaConverters._

  val dbUrl = "jdbc:h2:file:./var/metastore_mutate_route;MODE=MYSQL;AUTO_SERVER=true"
  val config =
    ConfigFactory.parseMap(Map("db.default.url" -> dbUrl).asJava)
  lazy val s2graph = new S2Graph(config.withFallback(ConfigFactory.load()))
  override val logger = LoggerFactory.getLogger(this.getClass)

  override def afterAll(): Unit = {
    s2graph.shutdown(true)
  }

  lazy val routes = mutateRoute

  val serviceName = "kakaoFavorites"
  val columnName = "userName"

  "MutateRoute" should {

    "be able to insert vertex (POST /mutate/vertex/insert)" in {
      s2graph.management.createService(serviceName, "localhost", s"${serviceName}-dev", 1, None)
      s2graph.management.createServiceColumn(serviceName, columnName, "string", Seq(Prop("age", "0", "integer")))

      // {"timestamp": 10, "serviceName": "s2graph", "columnName": "user", "id": 1, "props": {}}
      val param = Json.obj(
        "timestamp" -> 10,
        "serviceName" -> serviceName,
        "columnName" -> columnName,
        "id" -> "user_a",
        "props" -> Json.obj(
          "age" -> 20
        )
      )

      val entity = Marshal(param).to[MessageEntity].futureValue
      val request = Post("/vertex/insert").withEntity(entity)

      request ~> routes ~> check {
        status should ===(StatusCodes.OK)
        contentType should ===(ContentTypes.`application/json`)

        val response = entityAs[JsValue]
        response should ===(Json.toJson(Seq(true)))
      }
    }
  }
} 
Example 43
Source File: AdminRouteSpec.scala    From incubator-s2graph   with Apache License 2.0 5 votes vote down vote up
package org.apache.s2graph.http

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model._
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.typesafe.config.ConfigFactory
import org.apache.s2graph.core.Management.JsonModel.Prop
import org.apache.s2graph.core.S2Graph
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}
import org.slf4j.LoggerFactory
import play.api.libs.json.{JsString, JsValue, Json}

class AdminRoutesSpec extends WordSpec with Matchers with ScalaFutures with ScalatestRouteTest with S2GraphAdminRoute with BeforeAndAfterAll {
  import scala.collection.JavaConverters._

  val dbUrl = "jdbc:h2:file:./var/metastore_admin_route;MODE=MYSQL;AUTO_SERVER=true"
  val config =
    ConfigFactory.parseMap(Map("db.default.url" -> dbUrl).asJava)
  lazy val s2graph = new S2Graph(config.withFallback(ConfigFactory.load()))
  override val logger = LoggerFactory.getLogger(this.getClass)

  override def afterAll(): Unit = {
    s2graph.shutdown(true)
  }

  lazy val routes = adminRoute

  val serviceName = "kakaoFavorites"
  val columnName = "userName"

  "AdminRoute" should {
    "be able to create service (POST /createService)" in {
      val serviceParam = Json.obj(
        "serviceName" -> serviceName,
        "compressionAlgorithm" -> "gz"
      )

      val serviceEntity = Marshal(serviceParam).to[MessageEntity].futureValue
      val request = Post("/createService").withEntity(serviceEntity)

      request ~> routes ~> check {
        status should ===(StatusCodes.Created)
        contentType should ===(ContentTypes.`application/json`)

        val response = entityAs[JsValue]

        (response \\ "name").head should ===(JsString("kakaoFavorites"))
        (response \\ "status").head should ===(JsString("ok"))
      }
    }

    "return service if present (GET /getService/{serviceName})" in {
      val request = HttpRequest(uri = s"/getService/$serviceName")

      request ~> routes ~> check {
        status should ===(StatusCodes.OK)
        contentType should ===(ContentTypes.`application/json`)

        val response = entityAs[JsValue]

        (response \\ "name").head should ===(JsString("kakaoFavorites"))
      }
    }

    "be able to create serviceColumn (POST /createServiceColumn)" in {
      val serviceColumnParam = Json.obj(
        "serviceName" -> serviceName,
        "columnName" -> columnName,
        "columnType" -> "string",
        "props" -> Json.toJson(
          Seq(
            Json.obj("name" -> "age", "defaultValue" -> "-1", "dataType" -> "integer")
          )
        )
      )

      val serviceColumnEntity = Marshal(serviceColumnParam).to[MessageEntity].futureValue
      val request = Post("/createServiceColumn").withEntity(serviceColumnEntity)

      request ~> routes ~> check {
        status should ===(StatusCodes.Created)
        contentType should ===(ContentTypes.`application/json`)

        val response = entityAs[JsValue]

        (response \\ "serviceName").head should ===(JsString("kakaoFavorites"))
        (response \\ "columnName").head should ===(JsString("userName"))
        (response \\ "status").head should ===(JsString("ok"))
      }
    }
  }
} 
Example 44
Source File: CreateExchangeTransactionActor.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.actors.tx

import akka.actor.{Actor, ActorRef, Props}
import com.wavesplatform.dex.actors.tx.CreateExchangeTransactionActor.OrderExecutedObserved
import com.wavesplatform.dex.domain.account.Address
import com.wavesplatform.dex.domain.utils.ScorexLogging
import com.wavesplatform.dex.model.Events.{ExchangeTransactionCreated, OrderExecuted}
import com.wavesplatform.dex.model.ExchangeTransactionCreator.CreateTransaction
import play.api.libs.json.Json

import scala.collection.mutable


class CreateExchangeTransactionActor(createTransaction: CreateTransaction, recipients: List[ActorRef]) extends Actor with ScorexLogging {

  private val pendingEvents = mutable.Set.empty[OrderExecuted]

  override def preStart(): Unit = context.system.eventStream.subscribe(self, classOf[OrderExecutedObserved])

  override def receive: Receive = {
    case OrderExecutedObserved(sender, event) =>
      val sameOwner = event.counter.order.sender == event.submitted.order.sender
      log.debug(s"Execution observed at $sender for OrderExecuted(${event.submitted.order.id()}, ${event.counter.order
        .id()}), amount=${event.executedAmount})${if (sameOwner) " Same owner for both orders" else ""}")
      if (sameOwner || pendingEvents.contains(event)) {
        import event.{counter, submitted}
        createTransaction(event) match {
          case Right(tx) =>
            log.info(s"Created transaction: $tx")
            val created = ExchangeTransactionCreated(tx)
            recipients.foreach(_ ! created)
          case Left(ex) =>
            log.warn(
              s"""Can't create tx: $ex
               |o1: (amount=${submitted.amount}, fee=${submitted.fee}): ${Json.prettyPrint(submitted.order.json())}
               |o2: (amount=${counter.amount}, fee=${counter.fee}): ${Json.prettyPrint(counter.order.json())}""".stripMargin
            )
        }

        pendingEvents -= event
      } else pendingEvents += event
  }
}

object CreateExchangeTransactionActor {
  val name = "create-exchange-tx"

  case class OrderExecutedObserved(sender: Address, event: OrderExecuted)

  def props(createTransaction: CreateTransaction, recipients: List[ActorRef]): Props =
    Props(new CreateExchangeTransactionActor(createTransaction, recipients))
} 
Example 45
Source File: DexRestConnector.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.tool.connectors

import cats.syntax.option._
import com.google.common.primitives.Longs
import com.wavesplatform.dex.api.http.protocol.HttpCancelOrder
import com.wavesplatform.dex.cli.ErrorOr
import com.wavesplatform.dex.domain.account.KeyPair
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.domain.crypto
import com.wavesplatform.dex.domain.order.Order
import com.wavesplatform.dex.tool.connectors.RestConnector.ErrorOrJsonResponse
import play.api.libs.json.{JsValue, Json}
import sttp.client._
import sttp.model.MediaType
import sttp.model.Uri.QuerySegment

case class DexRestConnector(target: String) extends RestConnector {

  private val apiUri = s"$targetUri/matcher"

  private def mkCancelRequest(orderId: Order.Id, owner: KeyPair): HttpCancelOrder = {
    val cancelRequest = HttpCancelOrder(owner, orderId.some, None, Array.emptyByteArray)
    val signature     = crypto.sign(owner, cancelRequest.toSign)
    cancelRequest.copy(signature = signature)
  }

  private def cancelOrdersByRequest(cancelRequest: HttpCancelOrder, assetPair: AssetPair): ErrorOrJsonResponse = mkResponse {
    _.post(uri"$apiUri/orderbook/${assetPair.amountAsset}/${assetPair.priceAsset}/cancel")
      .body(Json.stringify(Json toJson cancelRequest))
      .contentType(MediaType.ApplicationJson)
  }

  private def timestampAndSignatureHeaders(owner: KeyPair, timestamp: Long): Map[String, String] = Map(
    "Timestamp" -> timestamp.toString,
    "Signature" -> Base58.encode(crypto.sign(owner, owner.publicKey ++ Longs.toByteArray(timestamp)))
  )

  def placeOrder(order: Order): ErrorOrJsonResponse = mkResponse {
    _.post(uri"$apiUri/orderbook").body(order.jsonStr).contentType(MediaType.ApplicationJson)
  }

  def cancelOrder(orderId: Order.Id, assetPair: AssetPair, owner: KeyPair): ErrorOrJsonResponse =
    cancelOrdersByRequest(mkCancelRequest(orderId, owner), assetPair)

  def cancelOrder(order: Order, owner: KeyPair): ErrorOrJsonResponse = cancelOrder(order.id(), order.assetPair, owner)

  def getOrderStatus(orderId: Order.Id, assetPair: AssetPair): ErrorOrJsonResponse = mkResponse {
    _.get(uri"$apiUri/orderbook/${assetPair.amountAsset}/${assetPair.priceAsset}/$orderId")
  }

  def getTxsByOrderId(id: Order.Id): ErrorOr[Seq[JsValue]] = mkResponse { _.get(uri"$apiUri/transactions/$id") } map { _.as[Seq[JsValue]] }

  def waitForOrderStatus(orderId: Order.Id, assetPair: AssetPair, expectedStatusName: String): ErrorOrJsonResponse =
    repeatRequest { getOrderStatus(orderId, assetPair) } {
      _.map(json => (json \ "status").get.asOpt[String] contains expectedStatusName).getOrElse(false)
    }

  def waitForOrderStatus(order: Order, expectedStatusName: String): ErrorOrJsonResponse =
    waitForOrderStatus(order.id(), order.assetPair, expectedStatusName)

  def getActiveOrdersByPair(keyPair: KeyPair, assetPair: AssetPair): ErrorOr[Seq[JsValue]] = {
    val uri =
      uri"$apiUri/orderbook/${assetPair.amountAsset}/${assetPair.priceAsset}/publicKey/${keyPair.publicKey.toString}"
        .copy(querySegments = List(QuerySegment.KeyValue("activeOnly", "true")))
    mkResponse { _.get(uri).headers(timestampAndSignatureHeaders(keyPair, System.currentTimeMillis)) }.map(_.as[Seq[JsValue]])
  }

  def getMatcherSettings: ErrorOr[JsValue] = mkResponse { _.get(uri"$apiUri/settings") }
} 
Example 46
Source File: WsConnection.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.ws.connection

import java.util.concurrent.ConcurrentLinkedQueue

import akka.Done
import akka.actor.{ActorRef, ActorSystem, Status}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.ws.{BinaryMessage, Message, TextMessage, WebSocketRequest}
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.stream.{CompletionStrategy, Materializer, OverflowStrategy}
import com.wavesplatform.dex.api.ws.protocol.{WsClientMessage, WsMessage, WsPingOrPong, WsServerMessage}
import com.wavesplatform.dex.domain.utils.ScorexLogging
import play.api.libs.json.Json

import scala.collection.JavaConverters._
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.{Failure, Success, Try}

class WsConnection(uri: String, keepAlive: Boolean = true)(implicit system: ActorSystem, materializer: Materializer) extends ScorexLogging {

  log.info(s"""Connecting to Matcher WS API:
            |         URI = $uri
            |  Keep alive = $keepAlive""".stripMargin)

  import materializer.executionContext

  private val wsHandlerRef = system.actorOf(TestWsHandlerActor props keepAlive)

  protected def stringifyClientMessage(cm: WsClientMessage): TextMessage.Strict =
    WsMessage.toStrictTextMessage(cm)(WsClientMessage.wsClientMessageWrites)

  // From test to server
  private val source: Source[TextMessage.Strict, ActorRef] = {
    val completionMatcher: PartialFunction[Any, CompletionStrategy] = { case akka.actor.Status.Success(_) => CompletionStrategy.draining }
    val failureMatcher: PartialFunction[Any, Throwable]             = { case Status.Failure(cause)        => cause }

    Source
      .actorRef[WsClientMessage](completionMatcher, failureMatcher, 10, OverflowStrategy.fail)
      .map(stringifyClientMessage)
      .mapMaterializedValue { source =>
        wsHandlerRef.tell(TestWsHandlerActor.AssignSourceRef, source)
        source
      }
  }

  private val messagesBuffer: ConcurrentLinkedQueue[WsServerMessage] = new ConcurrentLinkedQueue[WsServerMessage]()

  // From server to test
  private val sink: Sink[Message, Future[Done]] = Sink.foreach {
    case tm: TextMessage =>
      for {
        strictText <- tm.toStrict(1.second).map(_.getStrictText)
        clientMessage <- {
          log.trace(s"Got $strictText")
          Try { Json.parse(strictText).as[WsServerMessage] } match {
            case Failure(exception) => Future.failed(exception)
            case Success(x) => {
              messagesBuffer.add(x)
              if (keepAlive) x match {
                case value: WsPingOrPong => wsHandlerRef ! value
                case _                   =>
              }
              Future.successful(x)
            }
          }
        }
      } yield clientMessage

    case bm: BinaryMessage =>
      bm.dataStream.runWith(Sink.ignore)
      Future.failed { new IllegalArgumentException("Binary messages are not supported") }
  }

  private val flow: Flow[Message, TextMessage.Strict, Future[Done]] = Flow.fromSinkAndSourceCoupled(sink, source).watchTermination() {
    case (_, f) =>
      f.onComplete {
        case Success(_) => log.info(s"WebSocket connection to $uri successfully closed")
        case Failure(e) => log.error(s"WebSocket connection to $uri closed with an error", e)
      }(materializer.executionContext)
      f
  }

  val (connectionResponse, closed) = Http().singleWebSocketRequest(WebSocketRequest(uri), flow)

  val connectionOpenedTs: Long                   = System.currentTimeMillis
  val connectionClosedTs: Future[Long]           = closed.map(_ => System.currentTimeMillis)
  val connectionLifetime: Future[FiniteDuration] = connectionClosedTs.map(cc => FiniteDuration(cc - connectionOpenedTs, MILLISECONDS))

  def messages: List[WsServerMessage] = messagesBuffer.iterator().asScala.toList
  def clearMessages(): Unit           = messagesBuffer.clear()

  def send(message: WsClientMessage): Unit = wsHandlerRef ! TestWsHandlerActor.SendToServer(message)

  def close(): Unit     = if (!isClosed) wsHandlerRef ! TestWsHandlerActor.CloseConnection
  def isClosed: Boolean = closed.isCompleted
} 
Example 47
Source File: HttpMarketStatus.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.actors.orderbook.OrderBookActor.MarketStatus
import com.wavesplatform.dex.domain.order.OrderType
import com.wavesplatform.dex.model.{LastTrade, LevelAgg}
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, OFormat}

case class HttpMarketStatus(@ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) lastPrice: Option[Long],
                            @ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) lastAmount: Option[Long],
                            @ApiModelProperty(
                              value = "Side (sell or buy)",
                              dataType = "string",
                              example = "buy",
                              allowEmptyValue = true
                            )
                            lastSide: Option[OrderType],
                            @ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) bid: Option[Long],
                            @ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) bidAmount: Option[Long],
                            @ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) ask: Option[Long],
                            @ApiModelProperty(
                              allowEmptyValue = true,
                              dataType = "integer"
                            ) askAmount: Option[Long]) {

  @ApiModelProperty(hidden = true)
  val lastTrade: Option[LastTrade] =
    for {
      lp <- lastPrice
      la <- lastAmount
      ls <- lastSide
    } yield LastTrade(lp, la, ls)

  @ApiModelProperty(hidden = true)
  val bestBid: Option[LevelAgg] =
    for {
      bba <- bidAmount
      bbp <- bid
    } yield LevelAgg(bba, bbp)

  @ApiModelProperty(hidden = true)
  val bestAsk: Option[LevelAgg] =
    for {
      baa <- askAmount
      bap <- ask
    } yield LevelAgg(baa, bap)
}

object HttpMarketStatus {

  def fromMarketStatus(ms: MarketStatus): HttpMarketStatus =
    HttpMarketStatus(
      lastPrice = ms.lastTrade.map(_.price),
      lastAmount = ms.lastTrade.map(_.amount),
      lastSide = ms.lastTrade.map(_.side),
      bid = ms.bestBid.map(_.price),
      bidAmount = ms.bestBid.map(_.amount),
      ask = ms.bestAsk.map(_.price),
      askAmount = ms.bestAsk.map(_.amount)
    )

  implicit val httpMarketStatusFormat: OFormat[HttpMarketStatus] = Json.format[HttpMarketStatus]
} 
Example 48
Source File: HttpOrderStatus.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import cats.syntax.option._
import com.wavesplatform.dex.api.http.entities.HttpOrderStatus.Status
import com.wavesplatform.dex.meta.getSimpleName
import com.wavesplatform.dex.model.OrderStatus
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Format, Json, Reads, Writes}

case class HttpOrderStatus(@ApiModelProperty(
                             dataType = "string",
                             allowableValues = "Accepted, NotFound, PartiallyFilled, Filled, Cancelled"
                           ) status: Status,
                           @ApiModelProperty(
                             value = "Filled amount of existed order",
                             dataType = "integer",
                             allowEmptyValue = true
                           ) filledAmount: Option[Long] = None,
                           @ApiModelProperty(
                             value = "Filled fee of existed order",
                             dataType = "integer",
                             allowEmptyValue = true
                           ) filledFee: Option[Long] = None,
                           @ApiModelProperty(
                             value = "Brief message in case of not existed order",
                             allowEmptyValue = true
                           ) message: Option[String] = None)

object HttpOrderStatus {

  implicit val httpOrderStatusFormat: Format[HttpOrderStatus] = Json.format

  def from(x: OrderStatus): HttpOrderStatus = x match {
    case OrderStatus.Accepted                                 => HttpOrderStatus(Status.Accepted)
    case OrderStatus.NotFound                                 => HttpOrderStatus(Status.NotFound, message = Some("The limit order is not found"))
    case OrderStatus.PartiallyFilled(filledAmount, filledFee) => HttpOrderStatus(Status.PartiallyFilled, filledAmount.some, filledFee.some)
    case OrderStatus.Filled(filledAmount, filledFee)          => HttpOrderStatus(Status.Filled, filledAmount.some, filledFee.some)
    case OrderStatus.Cancelled(filledAmount, filledFee)       => HttpOrderStatus(Status.Cancelled, filledAmount.some, filledFee.some)
  }

  sealed abstract class Status extends Product with Serializable {
    val name: String = getSimpleName(this)
  }

  object Status {

    case object Accepted        extends Status
    case object NotFound        extends Status
    case object PartiallyFilled extends Status
    case object Filled          extends Status
    case object Cancelled       extends Status

    val All = List(Accepted, NotFound, PartiallyFilled, Filled, Cancelled)

    implicit val format: Format[Status] = Format(
      Reads.StringReads.map { x =>
        All.find(_.name == x) match {
          case Some(r) => r
          case None    => throw new IllegalArgumentException(s"Can't parse '$x' as ApiOrderStatus.Status")
        }
      },
      Writes.StringWrites.contramap(_.name)
    )
  }
} 
Example 49
Source File: HttpSuccessfulBatchCancel.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import io.swagger.annotations.{ApiModel, ApiModelProperty}
import play.api.libs.json.{Format, Json}

@ApiModel(description = "Cancel of multiple orders", parent = classOf[HttpSuccessfulCancel])
case class HttpSuccessfulBatchCancel(
                                      @ApiModelProperty(
      value = "List of successful cancellation messages or errors",
      dataType = "[[Lcom.wavesplatform.dex.api.http.entities.HttpSuccessfulSingleCancel;",
    )
    message: List[List[Either[HttpError, HttpSuccessfulSingleCancel]]], // TODO: In new API: should be a map id -> cancel result
                                      @ApiModelProperty(value = "Success flag")
    override val success: Boolean = HttpSuccessfulCancel.success,
                                      @ApiModelProperty(
      value = "Status",
      example = "BatchCancelCompleted",
      required = false
    ) override val status: String = "BatchCancelCompleted")
    extends HttpSuccessfulCancel

object HttpSuccessfulBatchCancel {

  implicit val httpSuccessfulBatchCancelFormat: Format[HttpSuccessfulBatchCancel] = {

    implicit val ef: Format[Either[HttpError, HttpSuccessfulSingleCancel]] =
      com.wavesplatform.dex.json.eitherFormat[HttpError, HttpSuccessfulSingleCancel]

    Json.format
  }

  def apply(message: List[Either[HttpError, HttpSuccessfulSingleCancel]]): HttpSuccessfulBatchCancel =
    HttpSuccessfulBatchCancel(message = List(message))
} 
Example 50
Source File: HttpTradingMarkets.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.account.PublicKey
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, OFormat}

case class HttpTradingMarkets(@ApiModelProperty(
                                value = "Base58 encoded Matcher Public Key",
                                dataType = "string",
                                example = "HBqhfdFASRQ5eBBpu2y6c6KKi1az6bMx8v1JxX4iW1Q8",
                              ) matcherPublicKey: PublicKey,
                              @ApiModelProperty(
                                value = "Market data with meta information",
                                dataType = "[Lcom.wavesplatform.dex.api.http.entities.HttpMarketDataWithMeta;",
                              ) markets: Seq[HttpMarketDataWithMeta])

object HttpTradingMarkets {
  implicit val httpTradingMarketsFormat: OFormat[HttpTradingMarkets] = Json.format[HttpTradingMarkets]
} 
Example 51
Source File: HttpOrderBookInfo.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, OFormat}

case class HttpOrderBookInfo(@ApiModelProperty(
                              value = "Restrictions of orders' amount and price",
                              allowEmptyValue = true
                            ) restrictions: Option[HttpOrderRestrictions],
                             @ApiModelProperty(
                              value = "Matching rules, tick size in particular",
                              allowEmptyValue = true
                            )
                            matchingRules: HttpMatchingRules)

object HttpOrderBookInfo {
  implicit val httpOrderBookInfoFormat: OFormat[HttpOrderBookInfo] = Json.format[HttpOrderBookInfo]
} 
Example 52
Source File: HttpV1OrderBook.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import java.nio.charset.StandardCharsets

import akka.http.scaladsl.model.{HttpEntity, HttpResponse}
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, Reads}

case class HttpV1OrderBook(@ApiModelProperty(value = "Timestamp of the last Order Book update") timestamp: Long,
                           @ApiModelProperty(
                             value = "List of aggregated denormalized bid levels [price, amount]",
                             dataType = "[[Ljava.lang.String;",
                             example = """[ [ "1.18", "43800.00000000" ], [ "1.17", "52187.00000000" ], [ "1.16", "809.00000000" ] ]"""
                           ) bids: List[HttpV1LevelAgg],
                           @ApiModelProperty(
                             value = "List of aggregated denormalized ask levels [price, amount]",
                             dataType = "[[Ljava.lang.String;",
                             example = """[ [ "1.19", "2134.00000000" ], [ "1.20", "747.00000000" ] ]"""
                           ) asks: List[HttpV1LevelAgg])

object HttpV1OrderBook {

  implicit val httpV1OrderBookReads: Reads[HttpV1OrderBook] = Json.reads

  def fromHttpResponse(response: HttpResponse): HttpV1OrderBook =
    Json.parse(response.entity.asInstanceOf[HttpEntity.Strict].getData().decodeString(StandardCharsets.UTF_8)).as[HttpV1OrderBook]
} 
Example 53
Source File: HttpError.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.error.MatcherError
import play.api.libs.json.{Format, JsObject, Json}

case class HttpError(error: Int,
                     message: String,
                     template: String,
                     params: Option[JsObject] = None,
                     status: String, // @deprecated(message = "This field is unnecessary", since = "1.2.0")
                     success: Boolean = false,
)
object HttpError {

  implicit val httpErrorFormat: Format[HttpError] = Json.format

  def apply(error: Int, message: String, template: String, params: JsObject, status: String): HttpError = new HttpError(
    error = error,
    message = message,
    template = template,
    params = Some(params),
    status = status
  )

  def from(x: MatcherError, status: String): HttpError = HttpError(
    error = x.code,
    message = x.message.text,
    template = x.message.template,
    params = if (x.message.params == JsObject.empty) None else Some(x.message.params),
    status = status
  )
} 
Example 54
Source File: HttpOrderBookHistoryItem.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.{Asset, AssetPair}
import com.wavesplatform.dex.domain.order.{Order, OrderType}
import com.wavesplatform.dex.model.{AcceptedOrderType, OrderInfo, OrderStatus}
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, OFormat}

case class HttpOrderBookHistoryItem(@ApiModelProperty(
                                      value = "Base58 encoded Order ID",
                                      dataType = "string",
                                      example = "7VEr4T9icqopHWLawGAZ7AQiJbjAcnzXn65ekYvbpwnN"
                                    ) id: Order.Id,
                                    @ApiModelProperty(
                                      value = "Order side (sell or buy)",
                                      dataType = "string",
                                      example = "sell"
                                    ) `type`: OrderType,
                                    @ApiModelProperty(
                                      value = "Order type (limit or market)",
                                      dataType = "string",
                                      example = "limit"
                                    ) orderType: AcceptedOrderType,
                                    @ApiModelProperty() amount: Long,
                                    @ApiModelProperty() filled: Long,
                                    @ApiModelProperty() price: Long,
                                    @ApiModelProperty() fee: Long,
                                    @ApiModelProperty() filledFee: Long,
                                    @ApiModelProperty(
                                      value = "Base58 encoded Matcher fee asset ID",
                                      dataType = "string",
                                      example = "6RQYnag6kTXaoGi3yPmX9JMpPya8WQntSohisKKCMGr"
                                    ) feeAsset: Asset,
                                    @ApiModelProperty() timestamp: Long,
                                    @ApiModelProperty(
                                      value = "Status",
                                      allowableValues = "Accepted, NotFound, PartiallyFilled, Filled, Cancelled"
                                    ) status: String,
                                    @ApiModelProperty() assetPair: AssetPair,
                                    @ApiModelProperty(value = "Average weighed price") avgWeighedPrice: Long,
                                    @ApiModelProperty(
                                      value = "Order version",
                                      dataType = "integer",
                                      example = "3"
                                    ) version: Byte)

object HttpOrderBookHistoryItem {

  implicit val httpOrderBookHistoryItemFormat: OFormat[HttpOrderBookHistoryItem] = Json.format

  def fromOrderInfo(id: Order.Id, info: OrderInfo[OrderStatus]): HttpOrderBookHistoryItem = HttpOrderBookHistoryItem(
    id = id,
    `type` = info.side,
    orderType = info.orderType,
    amount = info.amount,
    filled = info.status.filledAmount,
    price = info.price,
    fee = info.matcherFee,
    filledFee = info.status.filledFee,
    feeAsset = info.feeAsset,
    timestamp = info.timestamp,
    status = info.status.name,
    assetPair = info.assetPair,
    avgWeighedPrice = info.avgWeighedPrice,
    version = info.orderVersion
  )
} 
Example 55
Source File: HttpOrderRestrictions.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.json
import com.wavesplatform.dex.settings.OrderRestrictionsSettings
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Format, Json, OFormat}

case class HttpOrderRestrictions(@ApiModelProperty(dataType = "string", example = "0.001") stepAmount: Double,
                                 @ApiModelProperty(dataType = "string", example = "1000000") minAmount: Double,
                                 @ApiModelProperty(dataType = "string", example = "0.00000001") maxAmount: Double,
                                 @ApiModelProperty(dataType = "string", example = "0.001") stepPrice: Double,
                                 @ApiModelProperty(dataType = "string", example = "100000") minPrice: Double,
                                 @ApiModelProperty(dataType = "string", example = "0.00000001") maxPrice: Double)

object HttpOrderRestrictions {

  implicit val doubleFormat: Format[Double]                                = json.stringAsDoubleFormat
  implicit val httpOrderRestrictionsFormat: OFormat[HttpOrderRestrictions] = Json.format[HttpOrderRestrictions]

  def fromSettings(settings: OrderRestrictionsSettings): HttpOrderRestrictions =
    HttpOrderRestrictions(
      stepAmount = settings.stepAmount,
      minAmount = settings.minAmount,
      maxAmount = settings.maxAmount,
      stepPrice = settings.stepPrice,
      minPrice = settings.minPrice,
      maxPrice = settings.maxPrice
    )
} 
Example 56
Source File: HttpMarketDataWithMeta.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset
import io.swagger.annotations.ApiModelProperty
import play.api.libs.json.{Json, OFormat}

case class HttpMarketDataWithMeta(
    @ApiModelProperty(
      value = "Base58 encoded amount asset ID",
      dataType = "string",
      example = "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS"
    ) amountAsset: Asset,
    @ApiModelProperty(example = "BTC") amountAssetName: String,
    @ApiModelProperty(value = "Info about amount asset decimals", allowEmptyValue = true) amountAssetInfo: Option[HttpAssetInfo],
    @ApiModelProperty(
      value = "Base58 encoded price asset ID",
      dataType = "string",
      example = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
    ) priceAsset: Asset,
    @ApiModelProperty(example = "USDT") priceAssetName: String,
    @ApiModelProperty(value = "Info about price asset decimals", allowEmptyValue = true) priceAssetInfo: Option[HttpAssetInfo],
    @ApiModelProperty() created: Long,
    @ApiModelProperty(allowEmptyValue = true) restrictions: Option[HttpOrderRestrictions],
    @ApiModelProperty() matchingRules: HttpMatchingRules)

object HttpMarketDataWithMeta {
  implicit val httpMarketDataWithMetaFormat: OFormat[HttpMarketDataWithMeta] = Json.format[HttpMarketDataWithMeta]
} 
Example 57
Source File: OrderBookHttpInfo.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http

import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
import com.wavesplatform.dex.actors.OrderBookAskAdapter
import com.wavesplatform.dex.actors.orderbook.AggregatedOrderBookActor.Depth
import com.wavesplatform.dex.api.http.entities.MatcherResponse.toHttpResponse
import com.wavesplatform.dex.api.http.entities.{HttpMarketStatus, HttpOrderBook, OrderBookUnavailable, SimpleResponse}
import com.wavesplatform.dex.domain.asset.{Asset, AssetPair}
import com.wavesplatform.dex.model.MatcherModel.{DecimalsFormat, Denormalized}
import com.wavesplatform.dex.time.Time
import play.api.libs.json.Json

import scala.concurrent.{ExecutionContext, Future}

class OrderBookHttpInfo(settings: OrderBookHttpInfo.Settings, askAdapter: OrderBookAskAdapter, time: Time, assetDecimals: Asset => Option[Int])(
    implicit ec: ExecutionContext) {

  private val marketStatusNotFound = toHttpResponse(
    SimpleResponse(StatusCodes.NotFound, Json.obj("message" -> "There is no information about this asset pair"))
  )

  def getMarketStatus(assetPair: AssetPair): Future[HttpResponse] =
    askAdapter.getMarketStatus(assetPair).map {
      case Left(e) => toHttpResponse(OrderBookUnavailable(e))
      case Right(maybeMarketStatus) =>
        maybeMarketStatus match {
          case Some(ms) => toHttpResponse(SimpleResponse(HttpMarketStatus fromMarketStatus ms))
          case None     => marketStatusNotFound
        }
    }

  def getHttpView(assetPair: AssetPair, format: DecimalsFormat, depth: Option[Depth]): Future[HttpResponse] =
    askAdapter.getHttpView(assetPair, format, settings.nearestBigger(depth)).map {
      case Right(x) => x.getOrElse(getDefaultHttpView(assetPair, format))
      case Left(e)  => toHttpResponse(OrderBookUnavailable(e))
    }

  private def getDefaultHttpView(assetPair: AssetPair, format: DecimalsFormat): HttpResponse = {
    val entity = HttpOrderBook(time.correctedTime(), assetPair, Seq.empty, Seq.empty, assetPairDecimals(assetPair, format))
    HttpResponse(
      entity = HttpEntity(
        ContentTypes.`application/json`,
        HttpOrderBook.toJson(entity)
      )
    )
  }

  private def assetPairDecimals(assetPair: AssetPair, format: DecimalsFormat): Option[(Depth, Depth)] = format match {
    case Denormalized => assetDecimals(assetPair.amountAsset).zip(assetDecimals(assetPair.priceAsset)).headOption
    case _            => None
  }
}

object OrderBookHttpInfo {
  case class Settings(depthRanges: List[Int], defaultDepth: Option[Int]) {
    def nearestBigger(to: Option[Int]): Int =
      to.orElse(defaultDepth)
        .flatMap(desiredDepth => depthRanges.find(_ >= desiredDepth))
        .getOrElse(depthRanges.max)
  }
} 
Example 58
Source File: JwtUtils.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.auth

import java.security

import com.wavesplatform.dex.api.ws.protocol.WsAddressSubscribe.JwtPayload
import com.wavesplatform.dex.domain.account.{AddressScheme, KeyPair, PublicKey}
import com.wavesplatform.dex.domain.bytes.ByteStr
import pdi.jwt.{JwtAlgorithm, JwtJson}
import play.api.libs.json.{JsObject, Json}

import scala.concurrent.duration.{DurationInt, FiniteDuration}

trait JwtUtils {

  def mkJwt(authServiceKeyPair: security.KeyPair, payload: JwtPayload): String = mkJwt(authServiceKeyPair, Json.toJsObject(payload))
  def mkJwt(authServiceKeyPrivateKey: security.PrivateKey, payload: JsObject): String =
    JwtJson.encode(payload, authServiceKeyPrivateKey, JwtAlgorithm.RS256)
  def mkJwt(authServiceKeyPair: security.KeyPair, payload: JsObject): String =
    JwtJson.encode(payload, authServiceKeyPair.getPrivate, JwtAlgorithm.RS256)

  def mkJwtSignedPayload(clientKeyPair: KeyPair, networkByte: Byte = AddressScheme.current.chainId, lifetime: FiniteDuration = 1.hour): JwtPayload =
    mkJwtNotSignedPayload(clientKeyPair, networkByte, lifetime).signed(clientKeyPair)

  def mkJwtNotSignedPayload(clientPublicKey: PublicKey,
                            networkByte: Byte = AddressScheme.current.chainId,
                            lifetime: FiniteDuration = 1.hour): JwtPayload = {
    val exp = System.currentTimeMillis() / 1000 + lifetime.toSeconds
    JwtPayload(
      signature = ByteStr(Array.emptyByteArray),
      publicKey = clientPublicKey,
      networkByte = networkByte.toChar.toString,
      clientId = "test",
      firstTokenExpirationInSeconds = exp,
      activeTokenExpirationInSeconds = exp,
      scope = List("general")
    )
  }
}

object JwtUtils extends JwtUtils 
Example 59
Source File: HttpSuccessfulPlaceSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.account.PublicKey
import com.wavesplatform.dex.domain.asset.Asset.IssuedAsset
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.domain.order.{OrderType, OrderV1}
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpSuccessfulPlaceSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json = """{
                       |  "message" : {
                       |    "version" : 1,
                       |    "id" : "6KUFD9a6acDVM2Y8wqiFrdt35FPE1WF5QgjpPJqtKrP9",
                       |    "sender" : "3MyE3MtSi6MkXLCu1m7fCsUoJYRt4iibUGS",
                       |    "senderPublicKey" : "CsoEGd7UrxjBWEdoXbwh1x5fT64NNP8nBJ65xuJRx851",
                       |    "matcherPublicKey" : "G67KDhqHdjNNb2tnHRgNbDppQEM9ySXdiBip577n2Xoj",
                       |    "assetPair" : {
                       |      "amountAsset" : "6RQYnag6kTXaoGi3yPmX9JMpPya8WQntSohisKKCMGr",
                       |      "priceAsset" : "8pBLJDEwWgrxxHHnVLYbjhUySKy1qteiZGqK8dJeHUA"
                       |    },
                       |    "orderType" : "buy",
                       |    "amount" : 7235959396154477,
                       |    "price" : 399,
                       |    "timestamp" : 1580225937287,
                       |    "expiration" : 1582677054923,
                       |    "matcherFee" : 5273291907571414,
                       |    "signature" : "5GHs8aQQ3pMEipyotwz6NyzzAQfxizRpzFg7vBsptkQDhxR58cuzkwL2P7XtkTB7KQU7vq6GyZnJTWab2bK3Nixj",
                       |    "proofs" : [ "5GHs8aQQ3pMEipyotwz6NyzzAQfxizRpzFg7vBsptkQDhxR58cuzkwL2P7XtkTB7KQU7vq6GyZnJTWab2bK3Nixj" ]
                       |  },
                       |  "success" : true,
                       |  "status" : "OrderAccepted"
                       |}""".stripMargin

  private val order = OrderV1(
    senderPublicKey = PublicKey(Base58.decode("CsoEGd7UrxjBWEdoXbwh1x5fT64NNP8nBJ65xuJRx851")),
    matcherPublicKey = PublicKey(Base58.decode("G67KDhqHdjNNb2tnHRgNbDppQEM9ySXdiBip577n2Xoj")),
    assetPair = AssetPair(
      amountAsset = IssuedAsset(ByteStr.decodeBase58("6RQYnag6kTXaoGi3yPmX9JMpPya8WQntSohisKKCMGr").get),
      priceAsset = IssuedAsset(ByteStr.decodeBase58("8pBLJDEwWgrxxHHnVLYbjhUySKy1qteiZGqK8dJeHUA").get),
    ),
    orderType = OrderType.BUY,
    amount = 7235959396154477L,
    price = 399L,
    timestamp = 1580225937287L,
    expiration = 1582677054923L,
    matcherFee = 5273291907571414L,
    signature = Base58.decode("5GHs8aQQ3pMEipyotwz6NyzzAQfxizRpzFg7vBsptkQDhxR58cuzkwL2P7XtkTB7KQU7vq6GyZnJTWab2bK3Nixj")
  )

  private val message = HttpSuccessfulPlace(order)

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpSuccessfulPlace] should matchTo(message)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(message)) should matchTo(json)
    }
  }
} 
Example 60
Source File: HttpOrderStatusSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.model.OrderStatus
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpOrderStatusSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  "backward JSON compatibility and converting from OrderStatus" - {
    Map[OrderStatus, String](
      OrderStatus.Accepted                 -> """{"status":"Accepted"}""",
      OrderStatus.NotFound                 -> """{"status":"NotFound","message":"The limit order is not found"}""",
      OrderStatus.PartiallyFilled(200, 10) -> """{"status":"PartiallyFilled","filledAmount":200,"filledFee":10}""",
      OrderStatus.Filled(201, 11)          -> """{"status":"Filled","filledAmount":201,"filledFee":11}""",
      OrderStatus.Cancelled(202, 12)       -> """{"status":"Cancelled","filledAmount":202,"filledFee":12}"""
    ).foreach {
      case (status, json) =>
        val apiStatus = HttpOrderStatus.from(status)

        status.name - {
          "deserialization" in {
            Json.parse(json).as[HttpOrderStatus] should matchTo(apiStatus)
          }

          "serialization" in {
            Json.stringify(Json.toJson(apiStatus)) should matchTo(json)
          }
        }
    }
  }
} 
Example 61
Source File: HttpSuccessfulSingleCancelSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpSuccessfulSingleCancelSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "orderId" : "CijYneWqeJwtYLQvP3T6nRNueTFSmB977ULUDBxPZJNH",
      |  "success" : true,
      |  "status" : "OrderCanceled"
      |}""".stripMargin

  private val message = HttpSuccessfulSingleCancel(orderId = ByteStr.decodeBase58("CijYneWqeJwtYLQvP3T6nRNueTFSmB977ULUDBxPZJNH").get)

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpSuccessfulSingleCancel] should matchTo(message)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(message)) should matchTo(json)
    }
  }
} 
Example 62
Source File: HttpTradingMarketsSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import cats.syntax.option._
import com.wavesplatform.dex.domain.account.PublicKey
import com.wavesplatform.dex.domain.asset.Asset
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpTradingMarketsSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val marketDataWithMetaJson = """{
                                         |  "amountAsset" : "89M5b2chgRya9A5WnJx4irNuKzXExdEko2m8jmzdFMX",
                                         |  "amountAssetName" : "AmountAsset",
                                         |  "amountAssetInfo" : {
                                         |    "decimals" : 8
                                         |  },
                                         |  "priceAsset" : "Chn6MVRNBk7mHNBQg67Zhc81aigaoZsLwwNo9QiJ5bd",
                                         |  "priceAssetName" : "PriceAsset",
                                         |  "priceAssetInfo" : {
                                         |    "decimals" : 8
                                         |  },
                                         |  "created" : 1591105681300,
                                         |  "matchingRules" : {
                                         |    "tickSize" : "0.1"
                                         |  }
                                         |}""".stripMargin

  private val tradingMarketsJson = """{
                                     |  "matcherPublicKey" : "J6ghck2hA2GNJTHGSLSeuCjKuLDGz8i83NfCMFVoWhvf",
                                     |  "markets" : [ {
                                     |    "amountAsset" : "89M5b2chgRya9A5WnJx4irNuKzXExdEko2m8jmzdFMX",
                                     |    "amountAssetName" : "AmountAsset",
                                     |    "amountAssetInfo" : {
                                     |      "decimals" : 8
                                     |    },
                                     |    "priceAsset" : "Chn6MVRNBk7mHNBQg67Zhc81aigaoZsLwwNo9QiJ5bd",
                                     |    "priceAssetName" : "PriceAsset",
                                     |    "priceAssetInfo" : {
                                     |      "decimals" : 8
                                     |    },
                                     |    "created" : 1591105681300,
                                     |    "matchingRules" : {
                                     |      "tickSize" : "0.1"
                                     |    }
                                     |  } ]
                                     |}""".stripMargin

  private val marketData =
    HttpMarketDataWithMeta(
      amountAsset = Asset.fromString("89M5b2chgRya9A5WnJx4irNuKzXExdEko2m8jmzdFMX").get,
      amountAssetName = "AmountAsset",
      amountAssetInfo = HttpAssetInfo(8).some,
      priceAsset = Asset.fromString("Chn6MVRNBk7mHNBQg67Zhc81aigaoZsLwwNo9QiJ5bd").get,
      priceAssetName = "PriceAsset",
      priceAssetInfo = HttpAssetInfo(8).some,
      created = 1591105681300L,
      restrictions = None,
      matchingRules = HttpMatchingRules(0.1)
    )

  private val tradingMarkets =
    HttpTradingMarkets(
      PublicKey.fromBase58String("J6ghck2hA2GNJTHGSLSeuCjKuLDGz8i83NfCMFVoWhvf").right.get,
      Seq(marketData)
    )

  "backward JSON compatibility" - {

    "Market data with meta" - {
      "deserialization" in {
        Json.parse(marketDataWithMetaJson).as[HttpMarketDataWithMeta] should matchTo(marketData)
      }

      "serialization" in {
        Json.prettyPrint(Json.toJson(marketData)) should matchTo(marketDataWithMetaJson)
      }
    }

    "Trading markets" - {
      "deserialization" in {
        Json.parse(tradingMarketsJson).as[HttpTradingMarkets] should matchTo(tradingMarkets)
      }

      "serialization" in {
        Json.prettyPrint(Json.toJson(tradingMarkets)) should matchTo(tradingMarketsJson)
      }
    }
  }
} 
Example 63
Source File: HttpBalanceSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpBalanceSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "WAVES" : 100,
      |  "2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh" : 300
      |}""".stripMargin

  private val issuedAsset = IssuedAsset(Base58.decode("2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh"))

  private val balance =
    Map(
      Waves       -> 100L,
      issuedAsset -> 300L
    )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpBalance] should matchTo(balance)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(balance)) should matchTo(json)
    }
  }
} 
Example 64
Source File: HttpErrorSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpErrorSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  // Note, we removed "result" : null , because it effectively equal to a missing field
  private val json =
    """{
      |  "error" : 3148040,
      |  "message" : "The order 979P14dmPrcmcYhLeMpJFMuDDchdBeL9ouMPUvvYu1YU has already been placed",
      |  "template" : "The order {{id}} has already been placed",
      |  "params" : {
      |    "id" : "979P14dmPrcmcYhLeMpJFMuDDchdBeL9ouMPUvvYu1YU"
      |  },
      |  "status" : "OrderRejected",
      |  "success" : false
      |}""".stripMargin

  private val message: HttpError = HttpError(
    error = 3148040,
    message = "The order 979P14dmPrcmcYhLeMpJFMuDDchdBeL9ouMPUvvYu1YU has already been placed",
    template = "The order {{id}} has already been placed",
    params = Json.obj("id" -> "979P14dmPrcmcYhLeMpJFMuDDchdBeL9ouMPUvvYu1YU"),
    status = "OrderRejected"
  )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpError] should matchTo(message)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(message)) should matchTo(json)
    }
  }
} 
Example 65
Source File: HttpMessageSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpMessageSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json    = """{"message":"test text"}"""
  private val message = HttpMessage("test text")

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpMessage] should matchTo(message)
    }

    "serialization" in {
      Json.stringify(Json.toJson(message)) should matchTo(json)
    }
  }
} 
Example 66
Source File: HttpOrderBookInfoSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpOrderBookInfoSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "restrictions" : {
      |    "stepAmount" : "0.00000001",
      |    "minAmount" : "0.0000002",
      |    "maxAmount" : "3000",
      |    "stepPrice" : "0.000004",
      |    "minPrice" : "0.00005",
      |    "maxPrice" : "6000"
      |  },
      |  "matchingRules" : {
      |    "tickSize" : "0.7"
      |  }
      |}""".stripMargin

  private val orderBookInfo = HttpOrderBookInfo(
    restrictions = Some(
      HttpOrderRestrictions(
        stepAmount = 0.00000001,
        minAmount = 0.0000002,
        maxAmount = 3000,
        stepPrice = 0.000004,
        minPrice = 0.00005,
        maxPrice = 6000
      )
    ),
    matchingRules = HttpMatchingRules(
      tickSize = 0.7
    )
  )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpOrderBookInfo] should matchTo(orderBookInfo)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(orderBookInfo)) should matchTo(json)
    }
  }
} 
Example 67
Source File: HttpMatcherPublicSettingsSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.account.PublicKey
import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpMatcherPublicSettingsSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "matcherPublicKey" : "2eEUvypDSivnzPiLrbYEW39SM8yMZ1aq4eJuiKfs4sEY",
      |  "matcherVersion" : "2.1.3.3",
      |  "priceAssets" : [ "WAVES", "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8" ],
      |  "orderFee" : {
      |    "fixed" : {
      |      "assetId" : "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8",
      |      "minFee" : 300000
      |    }
      |  },
      |  "orderVersions" : [ 1, 2, 3 ],
      |  "networkByte" : 83
      |}""".stripMargin

  private val issuedAsset = IssuedAsset(Base58.decode("4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8"))

  private val matcherPublicSettings =
    HttpMatcherPublicSettings(
      matcherPublicKey = PublicKey.fromBase58String("2eEUvypDSivnzPiLrbYEW39SM8yMZ1aq4eJuiKfs4sEY").right.get,
      matcherVersion = "2.1.3.3",
      priceAssets = Seq(Waves, issuedAsset),
      orderFee = HttpOrderFeeMode.FeeModeFixed(
        assetId = issuedAsset,
        minFee = 300000
      ),
      orderVersions = Seq(1, 2, 3),
      networkByte = 83
    )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpMatcherPublicSettings] should matchTo(matcherPublicSettings)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(matcherPublicSettings)) should matchTo(json)
    }
  }
} 
Example 68
Source File: HttpSnapshotOffsetsSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpSnapshotOffsetsSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh-WAVES" : 1
      |}""".stripMargin

  private val issuedAsset = IssuedAsset(Base58.decode("2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh"))

  private val snapshotOffsets = Map(
    AssetPair(issuedAsset, Waves) -> 1L
  )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpSnapshotOffsets] should matchTo(snapshotOffsets)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(snapshotOffsets)) should matchTo(json)
    }
  }
} 
Example 69
Source File: HttpOrderFeeModeSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.api.http.entities.HttpOrderFeeMode.{FeeModeDynamic, FeeModeFixed, FeeModePercent}
import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.settings.AssetType
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpOrderFeeModeSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val fixedModeJson: String = """{
                                          |  "fixed" : {
                                          |    "assetId" : "6suw3ZHbyk6jrM19n7Pvaih3zSPsAt3gKcY8AZPxQYQf",
                                          |    "minFee" : 1
                                          |  }
                                          |}""".stripMargin

  private val fixedMode: HttpOrderFeeMode = FeeModeFixed(IssuedAsset(Base58.decode("6suw3ZHbyk6jrM19n7Pvaih3zSPsAt3gKcY8AZPxQYQf")), 1)

  private val dynamicModeJson: String = """{
                                          |  "dynamic" : {
                                          |    "baseFee" : 600000,
                                          |    "rates" : {
                                          |      "WAVES" : 1
                                          |    }
                                          |  }
                                          |}""".stripMargin

  private val percentModeJson: String = """{
                                          |  "percent" : {
                                          |    "type" : "price",
                                          |    "minFee" : 0.14
                                          |  }
                                          |}""".stripMargin

  private val percentMode: HttpOrderFeeMode = FeeModePercent(AssetType.PRICE, 0.14)

  private val dynamicMode: HttpOrderFeeMode = FeeModeDynamic(600000, Map(Waves -> 1))

  "ApiOrderFeeMode" - {
    "Dynamic" - {
      "backward JSON compatibility" - {
        "deserialization" in {
          Json.parse(dynamicModeJson).as[HttpOrderFeeMode] should matchTo(dynamicMode)
        }
        "serialization" in {
          Json.prettyPrint(Json.toJson(dynamicMode)) should matchTo(dynamicModeJson)
        }
      }
    }

    "Fixed" - {
      "backward JSON compatibility" - {
        "deserialization" in {
          Json.parse(fixedModeJson).as[HttpOrderFeeMode] should matchTo(fixedMode)
        }
        "serialization" in {
          Json.prettyPrint(Json.toJson(fixedMode)) should matchTo(fixedModeJson)
        }
      }
    }

    "Percent" - {
      "backward JSON compatibility" - {
        "deserialization" in {
          Json.parse(percentModeJson).as[HttpOrderFeeMode] should matchTo(percentMode)
        }
        "serialization" in {
          Json.prettyPrint(Json.toJson(percentMode)) should matchTo(percentModeJson)
        }
      }
    }
  }
} 
Example 70
Source File: HttpOrderBookHistoryItemSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.domain.order.OrderType
import com.wavesplatform.dex.model.{AcceptedOrderType, OrderStatus}
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpOrderBookHistoryItemSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "id" : "7VEr4T9icqopHWLawGAZ7AQiJbjAcnzXn65ekYvbpwnN",
      |  "type" : "buy",
      |  "orderType" : "limit",
      |  "amount" : 7757865201004347,
      |  "filled" : 0,
      |  "price" : 489,
      |  "fee" : 6345852410462127,
      |  "filledFee" : 0,
      |  "feeAsset" : "WAVES",
      |  "timestamp" : 1578074613225,
      |  "status" : "Accepted",
      |  "assetPair" : {
      |    "amountAsset" : "6rRegyHpdvZBENW4mowKYtKMDs2xpxmMbyNMRMZaZQ7",
      |    "priceAsset" : "8pFqaP5CtPB4kP87gpu2T7vB4LxdfoH9e5mSPQduhCc"
      |  },
      |  "avgWeighedPrice" : 0,
      |  "version" : 3
      |}""".stripMargin

  private val historyItem =
    HttpOrderBookHistoryItem(
      id = ByteStr.decodeBase58("7VEr4T9icqopHWLawGAZ7AQiJbjAcnzXn65ekYvbpwnN").get,
      `type` = OrderType.BUY,
      orderType = AcceptedOrderType.Limit,
      amount = 7757865201004347L,
      filled = 0L,
      price = 489L,
      fee = 6345852410462127L,
      filledFee = 0L,
      feeAsset = Waves,
      timestamp = 1578074613225L,
      status = OrderStatus.Accepted.name,
      assetPair = AssetPair(
        IssuedAsset(ByteStr.decodeBase58("6rRegyHpdvZBENW4mowKYtKMDs2xpxmMbyNMRMZaZQ7").get),
        IssuedAsset(ByteStr.decodeBase58("8pFqaP5CtPB4kP87gpu2T7vB4LxdfoH9e5mSPQduhCc").get)
      ),
      avgWeighedPrice = 0L,
      version = 3
    )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpOrderBookHistoryItem] should matchTo(historyItem)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(historyItem)) should matchTo(json)
    }
  }
} 
Example 71
Source File: HttpSuccessfulBatchCancelSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpSuccessfulBatchCancelSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  // Note, we removed "result" : null , because it effectively equal to a missing field
  private val json =
    """{
      |  "message" : [ [ {
      |    "orderId" : "8D36dK4snBwJHH9qfDyGo6xP5C4rCH2JPhPbbaJn5mLK",
      |    "success" : true,
      |    "status" : "OrderCanceled"
      |  }, {
      |    "error" : 25601,
      |    "message" : "Can not persist event, please retry later or contact with the administrator",
      |    "template" : "Can not persist event, please retry later or contact with the administrator",
      |    "status" : "OrderCancelRejected",
      |    "success" : false
      |  } ] ],
      |  "success" : true,
      |  "status" : "BatchCancelCompleted"
      |}""".stripMargin

  private val message = HttpSuccessfulBatchCancel(
    List(
      Right(HttpSuccessfulSingleCancel(orderId = ByteStr.decodeBase58("8D36dK4snBwJHH9qfDyGo6xP5C4rCH2JPhPbbaJn5mLK").get)),
      Left(
        HttpError(
          error = 25601,
          message = "Can not persist event, please retry later or contact with the administrator",
          template = "Can not persist event, please retry later or contact with the administrator",
          status = "OrderCancelRejected"
        )
      )
    )
  )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpSuccessfulBatchCancel] should matchTo(message)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(message)) should matchTo(json)
    }
  }
} 
Example 72
Source File: HttpMarketStatusSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import cats.syntax.option._
import com.wavesplatform.dex.domain.order.OrderType
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.{JsBoolean, JsString, Json}

class HttpMarketStatusSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "lastPrice" : 1000,
      |  "lastAmount" : 2000,
      |  "lastSide" : "sell",
      |  "bid" : 2222,
      |  "bidAmount" : 1111,
      |  "ask" : 4444,
      |  "askAmount" : 3333,
      |  "success" : true,
      |  "status" : "SimpleResponse"
      |}""".stripMargin

  private val marketStatus =
    HttpMarketStatus(
      lastPrice = 1000L.some,
      lastAmount = 2000L.some,
      lastSide = OrderType.SELL.some,
      bid = 2222L.some,
      bidAmount = 1111L.some,
      ask = 4444L.some,
      askAmount = 3333L.some
    )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpMarketStatus] should matchTo(marketStatus)
    }

    "serialization" in {
      val marketStatusJson = Json.toJsObject(marketStatus) + ("success" -> JsBoolean(true)) + ("status" -> JsString("SimpleResponse"))
      Json.prettyPrint(marketStatusJson) should matchTo(json)
    }
  }
} 
Example 73
Source File: HttpV1OrderBookSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.asset.{Asset, AssetPair}
import com.wavesplatform.dex.error.ErrorFormatterContext
import com.wavesplatform.dex.model.LevelAgg
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpV1OrderBookSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json = """{
                       |  "timestamp" : 0,
                       |  "bids" : [ [ "1.18", "43800.00000000" ], [ "1.17", "52187.00000000" ], [ "1.16", "809.00000000" ] ],
                       |  "asks" : [ [ "1.19", "2134.00000000" ], [ "1.20", "747.00000000" ] ]
                       |}""".stripMargin

  private val usd: Asset   = IssuedAsset("USDN".getBytes)
  private val wavesUsdPair = AssetPair(Waves, usd)

  private implicit val efc: ErrorFormatterContext = {
    case `usd` => 2
    case _     => 8
  }

  private val bids = List(LevelAgg(4380000000000L, 118), LevelAgg(5218700000000L, 117), LevelAgg(80900000000L, 116))
  private val asks = List(LevelAgg(213400000000L, 119), LevelAgg(74700000000L, 120))

  private val orderBookV1 =
    HttpV1OrderBook(
      timestamp = 0,
      bids = bids.map(la => HttpV1LevelAgg.fromLevelAgg(la, wavesUsdPair)),
      asks = asks.map(la => HttpV1LevelAgg.fromLevelAgg(la, wavesUsdPair))
    )

  private val orderBookResult = HttpOrderBook(0, wavesUsdPair, bids, asks, Some(8 -> 2))

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpV1OrderBook] should matchTo(orderBookV1)
    }

    "serialization" in {
      Json.prettyPrint(Json.parse(HttpOrderBook toJson orderBookResult)) should matchTo(json)
    }
  }
} 
Example 74
Source File: HttpV0OrderBookSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.Waves
import com.wavesplatform.dex.domain.asset.{Asset, AssetPair}
import com.wavesplatform.dex.model.LevelAgg
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpV0OrderBookSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json = """{
                       |  "timestamp" : 0,
                       |  "pair" : {
                       |    "amountAsset" : "LWbazpyvj625QB6EMC1vQoMkrvn2DdKjYbuuEw2T2UF",
                       |    "priceAsset" : "WAVES"
                       |  },
                       |  "bids" : [ {
                       |    "amount" : 10000000000000,
                       |    "price" : 41
                       |  }, {
                       |    "amount" : 2500000000000,
                       |    "price" : 40
                       |  }, {
                       |    "amount" : 300000000000000,
                       |    "price" : 1
                       |  } ],
                       |  "asks" : [ {
                       |    "amount" : 50000000000,
                       |    "price" : 50
                       |  }, {
                       |    "amount" : 2500000000000,
                       |    "price" : 51
                       |  } ]
                       |}""".stripMargin

  private val assetPair = AssetPair(Asset.fromString("LWbazpyvj625QB6EMC1vQoMkrvn2DdKjYbuuEw2T2UF").get, Waves)
  private val bids      = List(LevelAgg(10000000000000L, 41), LevelAgg(2500000000000L, 40), LevelAgg(300000000000000L, 1))
  private val asks      = List(LevelAgg(50000000000L, 50), LevelAgg(2500000000000L, 51))

  private val orderBookV0     = HttpV0OrderBook(0, assetPair, bids.map(HttpV0LevelAgg.fromLevelAgg), asks.map(HttpV0LevelAgg.fromLevelAgg))
  private val orderBookResult = HttpOrderBook(0, assetPair, bids, asks)

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpV0OrderBook] should matchTo(orderBookV0)
    }

    "serialization" in {
      Json.prettyPrint(Json.parse(HttpOrderBook toJson orderBookResult)) should matchTo(json)
    }
  }
} 
Example 75
Source File: HttpRatesSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.http.entities

import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.test.matchers.DiffMatcherWithImplicits
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
import play.api.libs.json.Json

class HttpRatesSpec extends AnyFreeSpec with Matchers with DiffMatcherWithImplicits {

  private val json =
    """{
      |  "WAVES" : 1,
      |  "2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh" : 3
      |}""".stripMargin

  private val issuedAsset = IssuedAsset(Base58.decode("2gCPcEnoZa9LtZzZPFK9fJf7aWzvdBJUABayd1Zj5qFh"))

  private val rates =
    Map(
      Waves       -> 1d,
      issuedAsset -> 3d
    )

  "backward JSON compatibility" - {
    "deserialization" in {
      Json.parse(json).as[HttpRates] should matchTo(rates)
    }

    "serialization" in {
      Json.prettyPrint(Json.toJson(rates)) should matchTo(json)
    }
  }
} 
Example 76
Source File: KeyPair.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.domain.account

import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.domain.bytes.ByteStr._
import com.wavesplatform.dex.domain.bytes.codec.Base58
import com.wavesplatform.dex.domain.crypto
import com.wavesplatform.dex.domain.error.ValidationError.GenericError
import play.api.libs.json.{Format, Json, Writes}

import scala.util.{Failure, Success}

final case class KeyPair(seed: ByteStr) {
  lazy val (PrivateKey(privateKey), PublicKey(publicKey)) = crypto.createKeyPair(seed)
}

object KeyPair {

  def fromSeed(base58: String): Either[GenericError, KeyPair] = Base58.tryDecodeWithLimit(base58) match {
    case Success(x) => Right(KeyPair(x))
    case Failure(e) => Left(GenericError(s"Unable to get a private key from the seed '$base58': ${e.getMessage}"))
  }

  implicit class KeyPairImplicitOps(private val kp: KeyPair) extends AnyVal {
    def toAddress: Address = PublicKey.toAddress(kp)
  }

  implicit def toPublicKey(kp: KeyPair): PublicKey   = kp.publicKey
  implicit def toPrivateKey(kp: KeyPair): PrivateKey = kp.privateKey
  implicit def toAddress(keyPair: KeyPair): Address  = keyPair.toAddress

  implicit val jsonFormat: Format[KeyPair] = Format(
    byteStrFormat.map(KeyPair(_)),
    Writes(v => Json.obj("seed" -> Base58.encode(v.seed), "publicKey" -> v.publicKey, "privateKey" -> v.privateKey))
  )
} 
Example 77
Source File: OrderJsonSpec.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.domain.order

import cats.syntax.option._
import com.wavesplatform.dex.domain.account.KeyPair
import com.wavesplatform.dex.domain.asset.Asset.{IssuedAsset, Waves}
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.order.OrderJson.orderFormat
import com.wavesplatform.dex.domain.order.OrderOps._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import play.api.libs.json.Json

class OrderJsonSpec extends AnyWordSpecLike with Matchers {

  private val usd: IssuedAsset        = IssuedAsset("USDN".getBytes)
  private val wavesUsdPair: AssetPair = AssetPair(Waves, usd)

  private val senderKeyPair  = KeyPair("sender".getBytes)
  private val matcherKeyPair = KeyPair("matcher".getBytes)

  private val order: Order =
    OrderV3(
      senderKeyPair,
      matcherKeyPair,
      wavesUsdPair,
      OrderType.SELL,
      123456789L,
      119L,
      1578074613225L,
      1578077613225L,
      300000L,
      Waves
    )

  def getOrderJson(feeAssetRepresentation: Option[String]): String =
    s"""{
      |  "version" : 3,
      |  "id" : "HCXVwUaETvHySqRyJSZ2NbnLeqTYP2FBkbwecXmMdbM6",
      |  "sender" : "3N7YhNxYuoa59oCCMPuQRqSx6KM61FkGjYa",
      |  "senderPublicKey" : "226pFho3kqHiCoiQVAUq5MVFkg3KzGLc2zLNsbH8GmE7",
      |  "matcherPublicKey" : "J6ghck2hA2GNJTHGSLSeuCjKuLDGz8i83NfCMFVoWhvf",
      |  "assetPair" : {
      |    "amountAsset" : "WAVES",
      |    "priceAsset" : "3BVv85"
      |  },
      |  "orderType" : "sell",
      |  "amount" : 123456789,
      |  "price" : 119,
      |  "timestamp" : 1578074613225,
      |  "expiration" : 1578077613225,
      |  "matcherFee" : 300000,${feeAssetRepresentation.fold("")(str => s"""\n"matcherFeeAssetId" : $str,""")}
      |  "signature" : "7dsUd1bQZFWCEKyYqkPxd5AE7x88QUK6xJH86KcqtE2LHURxN92QEJRfojHkgezez6fppDGvTCUcr4ZmrPRKmTZ",
      |  "proofs" : [ "7dsUd1bQZFWCEKyYqkPxd5AE7x88QUK6xJH86KcqtE2LHURxN92QEJRfojHkgezez6fppDGvTCUcr4ZmrPRKmTZ" ]
      |}""".stripMargin

  "Domain OrderV3" should {

    "be deserialized from JSON" when {

      "matcherFeeAssetId passed as null" in {
        Json.parse(getOrderJson("null".some)).as[Order] updateProofs order.proofs shouldBe order
      }

      "matcherFeeAssetId passed as WAVES" in {
        Json.parse(getOrderJson("\"WAVES\"".some)).as[Order] updateProofs order.proofs shouldBe order
      }

      "matcherFeeAssetId wasn't passed" in {
        Json.parse(getOrderJson(None)).as[Order] updateProofs order.proofs shouldBe order
      }

      "matcherFeeAssetId passed as Issued asset" in {
        Json
          .parse(getOrderJson(s""""${usd.id}"""".some))
          .as[Order]
          .updateProofs(order.proofs)
          .updateFeeAsset(usd) shouldBe order.updateFeeAsset(usd)
      }
    }
  }
} 
Example 78
Source File: WsConnection.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.load.ws

import akka.Done
import akka.actor.{ActorRef, ActorSystem, Status}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.ws.{BinaryMessage, Message, TextMessage, WebSocketRequest}
import akka.stream.scaladsl.{Flow, Sink, Source}
import akka.stream.{CompletionStrategy, Materializer, OverflowStrategy}
import com.wavesplatform.dex.api.ws.connection.TestWsHandlerActor
import com.wavesplatform.dex.api.ws.protocol.{WsClientMessage, WsMessage, WsServerMessage}
import com.wavesplatform.dex.domain.utils.ScorexLogging
import play.api.libs.json.Json

import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
import scala.util.{Failure, Success, Try}

class WsConnection(uri: String, receive: WsServerMessage => Option[WsClientMessage])(implicit system: ActorSystem) extends ScorexLogging {

  import system.dispatcher
  private implicit val materializer = Materializer(system)
  private val wsHandlerRef          = system.actorOf(TestWsHandlerActor.props(keepAlive = true))

  log.info(s"Connecting to Matcher WS API: $uri")

  protected def stringifyClientMessage(cm: WsClientMessage): TextMessage.Strict =
    WsMessage.toStrictTextMessage(cm)(WsClientMessage.wsClientMessageWrites)

  // To server
  private val source: Source[TextMessage.Strict, ActorRef] = {
    val completionMatcher: PartialFunction[Any, CompletionStrategy] = { case akka.actor.Status.Success(_) => CompletionStrategy.draining }
    val failureMatcher: PartialFunction[Any, Throwable]             = { case Status.Failure(cause)        => cause }

    Source
      .actorRef[WsClientMessage](completionMatcher, failureMatcher, 10, OverflowStrategy.fail)
      .map(stringifyClientMessage)
      .mapMaterializedValue { source =>
        wsHandlerRef.tell(TestWsHandlerActor.AssignSourceRef, source)
        source
      }
  }

  // To client
  private val sink: Sink[Message, Future[Done]] = Sink.foreach {
    case tm: TextMessage => // TODO move to tests
      for {
        strictText <- tm.toStrict(1.second).map(_.getStrictText)
        clientMessage <- {
          log.trace(s"Got $strictText")
          Try { Json.parse(strictText).as[WsServerMessage] } match {
            case Failure(exception) => Future.failed(exception)
            case Success(x)         => Future.successful { receive(x).foreach(wsHandlerRef ! _) }
          }
        }
      } yield clientMessage

    case bm: BinaryMessage =>
      bm.dataStream.runWith(Sink.ignore)
      Future.failed { new IllegalArgumentException("Binary messages are not supported") }
  }

  private val flow: Flow[Message, TextMessage.Strict, Future[Done]] = Flow.fromSinkAndSourceCoupled(sink, source).watchTermination() {
    case (_, f) =>
      f.onComplete {
        case Success(_) => log.info(s"WebSocket connection to $uri successfully closed")
        case Failure(e) => log.error(s"WebSocket connection to $uri closed with an error", e)
      }(materializer.executionContext)
      f
  }

  val (connectionResponse, closed) = Http().singleWebSocketRequest(WebSocketRequest(uri), flow)

  def send(message: WsClientMessage): Unit = wsHandlerRef ! TestWsHandlerActor.SendToServer(message)

  def isClosed: Boolean = closed.isCompleted
  def close(): Future[Done] = {
    if (!isClosed) wsHandlerRef ! TestWsHandlerActor.CloseConnection
    closed
  }
} 
Example 79
Source File: GatlingFeeder.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.load

import java.io.{File, PrintWriter}
import java.security
import java.security.KeyFactory
import java.security.spec.PKCS8EncodedKeySpec
import java.util.Base64

import com.wavesplatform.dex.api.ws.protocol.WsAddressSubscribe.JwtPayload
import com.wavesplatform.dex.auth.JwtUtils
import com.wavesplatform.dex.domain.account.{AddressScheme, PrivateKey, PublicKey}
import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.wavesj.PrivateKeyAccount
import play.api.libs.json.Json

import scala.concurrent.duration._
import scala.io.Source
import scala.util.Random

object GatlingFeeder {

  def authServiceKeyPair(rawPrivateKey: String): security.PrivateKey = {
    val privateKeyContent = rawPrivateKey
      .replace("-----BEGIN PRIVATE KEY-----", "")
      .replace("-----END PRIVATE KEY-----", "")
      .replaceAll("\\n", "")

    val kf         = KeyFactory.getInstance("RSA")
    val ksPkcs8    = new PKCS8EncodedKeySpec(Base64.getDecoder.decode(privateKeyContent))
    val privateKey = kf.generatePrivate(ksPkcs8)

    privateKey
  }

  private def mkJwtSignedPayload(a: PrivateKeyAccount): JwtPayload = {
    val exp = System.currentTimeMillis() / 1000 + 24.hour.toSeconds
    JwtPayload(
      signature = ByteStr(Array.emptyByteArray),
      publicKey = PublicKey(a.getPublicKey),
      networkByte = AddressScheme.current.chainId.toChar.toString,
      clientId = "test",
      firstTokenExpirationInSeconds = exp,
      activeTokenExpirationInSeconds = exp,
      scope = List("general")
    ).signed(PrivateKey(a.getPrivateKey))
  }

  private def mkAusString(accountPrivateKey: PrivateKeyAccount, authKp: security.PrivateKey): String = {
    s"""{"T":"aus","S":"${accountPrivateKey.getAddress}","t":"jwt","j":"${JwtUtils.mkJwt(authKp,
                                                                                         Json.toJsObject(mkJwtSignedPayload(accountPrivateKey)))}"}"""
  }

  private def mkObsStrings(pairsFile: File, numberPerClient: Int): String = {
    val source = Source.fromFile(pairsFile)
    try {
      val pairs = Random.shuffle(source.getLines.toVector)
      require(numberPerClient <= pairs.size, "numberPerClient > available asset pairs in file")
      pairs.take(numberPerClient).map(x => s"""{"T":"obs","S":"$x","d":100}""").mkString(";")
    } finally source.close()
  }

  def mkFile(accountsNumber: Int,
             seedPrefix: String,
             authKp: security.PrivateKey,
             pairsFile: File,
             orderBookNumberPerAccount: Int,
             feederFile: File): Unit = {
    val output = new PrintWriter(feederFile, "utf-8")
    try {
      (0 until accountsNumber).foreach { i =>
        val pk = PrivateKeyAccount.fromSeed(s"$seedPrefix$i", 0, AddressScheme.current.chainId)
        output.println(s"""${pk.getAddress};${mkAusString(pk, authKp)};${mkObsStrings(pairsFile, orderBookNumberPerAccount)}""")
      }
    } finally output.close()
    println(s"Results have been saved to $feederFile")
  }
} 
Example 80
Source File: MatcherError.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.it.api.responses.dex

import play.api.libs.json.{Format, Json}
import shapeless.ops.hlist.{Mapper, ToTraversable, Zip}
import shapeless.{::, Generic, HList, HNil, Poly1}

// TODO use ApiError instead
case class MatcherError(error: Int, message: String, status: String, params: Option[MatcherError.Params])
object MatcherError {
  implicit val format: Format[MatcherError] = Json.format[MatcherError]

  case class Params(assetId: Option[String] = None, address: Option[String] = None, insignificantDecimals: Option[Int] = None) {
    def isEmpty: Boolean = assetId.isEmpty && address.isEmpty
  }

  object Params {
    implicit val format: Format[Params] = Json.format[Params]

    private object containsPoly extends Poly1 {
      implicit def contains[T: Ordering] = at[(Option[T], Option[T])] {
        case (Some(l), Some(r)) => l == r
        case (None, None)       => true
        case _                  => false
      }
    }

    private def internalContains[HParams <: HList, ZHParams <: HList, Booleans <: HList](obj: Params, part: Params)(
        implicit gen: Generic.Aux[Params, HParams],
        zip: Zip.Aux[HParams :: HParams :: HNil, ZHParams],
        mapper: Mapper.Aux[containsPoly.type, ZHParams, Booleans],
        toList: ToTraversable.Aux[Booleans, List, Boolean]): Boolean =
      gen.to(obj).zip(gen.to(part))(zip).map(containsPoly).toList[Boolean](toList).forall(identity)

    def contains(obj: Params, part: Params): Boolean = internalContains(obj, part)
  }
} 
Example 81
Source File: HasJwt.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.it.api.websockets

import java.security
import java.security.KeyPairGenerator
import java.util.Base64

import com.typesafe.config.{Config, ConfigFactory}
import com.wavesplatform.dex.api.ws.protocol.WsAddressSubscribe.JwtPayload
import com.wavesplatform.dex.auth.JwtUtils
import com.wavesplatform.dex.domain.account.KeyPair
import play.api.libs.json.Json

import scala.concurrent.duration.{FiniteDuration, _}

trait HasJwt extends JwtUtils {

  protected val authServiceKeyPair: security.KeyPair = {
    val kpg = KeyPairGenerator.getInstance("RSA")
    kpg.initialize(2048)
    kpg.generateKeyPair()
  }

  protected def jwtPublicKeyConfig: Config = ConfigFactory.parseString(
    s"""waves.dex.web-sockets.external-client-handler.jwt-public-key = \"\"\"-----BEGIN PUBLIC KEY-----
       |${Base64.getEncoder.encodeToString(authServiceKeyPair.getPublic.getEncoded).grouped(64).mkString("\n")}
       |-----END PUBLIC KEY-----\"\"\"
       |""".stripMargin
  )

  protected def mkJwt(payload: JwtPayload): String = mkJwt(authServiceKeyPair, Json.toJsObject(payload))

  protected def mkJwt(clientKeyPair: KeyPair, lifetime: FiniteDuration = 1.hour): String = {
    mkJwt(mkJwtSignedPayload(clientKeyPair, lifetime = lifetime))
  }
} 
Example 82
Source File: SemanticRepositorySpecs.scala    From daf-semantics   with Apache License 2.0 5 votes vote down vote up
package specs

import org.junit.runner.RunWith

import scala.concurrent.{ Await, Future }
import scala.concurrent.duration.Duration

import play.api.test._
import play.api.http.Status
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.ws.WSResponse
import play.api.libs.ws.ahc.AhcWSClient
import org.specs2.runner.JUnitRunner
import org.specs2.mutable.Specification
import play.api.libs.json.Json
//import it.almawave.linkeddata.kb.utils.ConfigHelper

import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
import play.twirl.api.Content
import play.api.test.Helpers._
import play.api.libs.json.JsObject
import java.io.File
import play.api.http.Writeable
import akka.stream.scaladsl.Source
import play.api.mvc.MultipartFormData
import play.api.libs.Files.TemporaryFile
import java.nio.file.Files
import org.asynchttpclient.AsyncHttpClient
import play.api.libs.ws.WS
import akka.util.ByteString
import play.api.mvc.MultipartFormData.DataPart
import play.api.mvc.MultipartFormData.FilePart
import akka.stream.scaladsl.FileIO
import play.api.libs.ws.WSClient

/*
 * TODO: REWRITE
 */
@RunWith(classOf[JUnitRunner])
class SemanticRepositorySpecs extends Specification {

  def application: Application = GuiceApplicationBuilder().build()

  "The semantic repository" should {

    "call kb/v1/contexts to obtain a list of contexts" in {
      new WithServer(app = application, port = 9999) {
        WsTestClient.withClient { implicit client =>

          val response: WSResponse = Await.result[WSResponse](
            client.url(s"http://localhost:${port}/kb/v1/contexts").execute,
            Duration.Inf)

          response.status must be equalTo Status.OK
          response.json.as[Seq[JsObject]].size must be equals 0
          // response.json.as[Seq[JsObject]].size must be greaterThan 0 // if pre-loaded ontologies!

        }
      }
    }

    "call kb/v1/contexts ensuring all contexts have triples" in {
      new WithServer(app = application, port = 9999) {
        WsTestClient.withClient { implicit client =>

          val response: WSResponse = Await.result[WSResponse](
            client.url(s"http://localhost:${port}/kb/v1/contexts").execute,
            Duration.Inf)

          val json_list = response.json.as[Seq[JsObject]]
          forall(json_list)((_) must not beNull)
          forall(json_list)(_.keys must contain("context", "triples"))
          forall(json_list)(item => (item \ "triples").get.as[Int] > 0)

        }
      }
    }

  }

} 
Example 83
Source File: TestSpec.scala    From intro-to-akka-streams   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.streams

import akka.NotUsed
import akka.actor.{ ActorRef, ActorSystem, PoisonPill }
import akka.event.{ Logging, LoggingAdapter }
import akka.stream.Materializer
import akka.stream.scaladsl.Source
import akka.stream.testkit.TestSubscriber
import akka.stream.testkit.scaladsl.TestSink
import akka.testkit.TestProbe
import akka.util.Timeout
import com.github.dnvriend.streams.util.ClasspathResources
import org.scalatest._
import org.scalatest.concurrent.{ Eventually, ScalaFutures }
import org.scalatestplus.play.guice.GuiceOneServerPerSuite
import play.api.inject.BindingKey
import play.api.libs.json.{ Format, Json }
import play.api.test.WsTestClient

import scala.collection.immutable._
import scala.concurrent.duration._
import scala.concurrent.{ ExecutionContext, Future }
import scala.reflect.ClassTag
import scala.util.Try

object Person {
  implicit val format: Format[Person] = Json.format[Person]
}

final case class Person(firstName: String, age: Int)

class TestSpec extends FlatSpec
    with Matchers
    with GivenWhenThen
    with OptionValues
    with TryValues
    with ScalaFutures
    with WsTestClient
    with BeforeAndAfterAll
    with BeforeAndAfterEach
    with Eventually
    with ClasspathResources
    with GuiceOneServerPerSuite {

  def getComponent[A: ClassTag] = app.injector.instanceOf[A]
  def getNamedComponent[A](name: String)(implicit ct: ClassTag[A]): A =
    app.injector.instanceOf[A](BindingKey(ct.runtimeClass.asInstanceOf[Class[A]]).qualifiedWith(name))

  // set the port number of the HTTP server
  override lazy val port: Int = 8081
  implicit val timeout: Timeout = 1.second
  implicit val pc: PatienceConfig = PatienceConfig(timeout = 30.seconds, interval = 300.millis)
  implicit val system: ActorSystem = getComponent[ActorSystem]
  implicit val ec: ExecutionContext = getComponent[ExecutionContext]
  implicit val mat: Materializer = getComponent[Materializer]
  val log: LoggingAdapter = Logging(system, this.getClass)

  // ================================== Supporting Operations ====================================
  def id: String = java.util.UUID.randomUUID().toString

  implicit class FutureToTry[T](f: Future[T]) {
    def toTry: Try[T] = Try(f.futureValue)
  }

  implicit class SourceOps[A](src: Source[A, NotUsed]) {
    def testProbe(f: TestSubscriber.Probe[A] ⇒ Unit): Unit =
      f(src.runWith(TestSink.probe(system)))
  }

  def withIterator[T](start: Int = 0)(f: Source[Int, NotUsed] ⇒ T): T =
    f(Source.fromIterator(() ⇒ Iterator from start))

  def fromCollection[A](xs: Iterable[A])(f: TestSubscriber.Probe[A] ⇒ Unit): Unit =
    f(Source(xs).runWith(TestSink.probe(system)))

  def killActors(refs: ActorRef*): Unit = {
    val tp = TestProbe()
    refs.foreach { ref ⇒
      tp watch ref
      tp.send(ref, PoisonPill)
      tp.expectTerminated(ref)
    }
  }
} 
Example 84
Source File: NationalInsuranceTaxYear.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.models

import org.joda.time.LocalDate
import play.api.libs.json.{Format, Json}

case class NationalInsuranceTaxYear(
                                     taxYear: String,
                                     qualifying: Boolean,
                                     classOneContributions: BigDecimal,
                                     classTwoCredits: Int,
                                     classThreeCredits: Int,
                                     otherCredits: Int,
                                     classThreePayable: BigDecimal,
                                     classThreePayableBy: Option[LocalDate],
                                     classThreePayableByPenalty: Option[LocalDate],
                                     payable: Boolean,
                                     underInvestigation: Boolean
                                   ) {

  def currentDateAfterCutOff(currentDate: LocalDate): Boolean = {
    classThreePayableBy match {
      case Some(classThreeDate) => currentDate.isAfter(classThreeDate)
      case None => payable
    }
  }

}



object NationalInsuranceTaxYear {
  implicit val formats: Format[NationalInsuranceTaxYear] = Json.format[NationalInsuranceTaxYear]
} 
Example 85
Source File: StatePensionConnector.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.connectors

import play.api.libs.json.{Format, Json, Writes}
import uk.gov.hmrc.domain.Nino
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.nisp.models.enums.APIType
import uk.gov.hmrc.nisp.models.{StatePension, StatePensionExclusion}
import uk.gov.hmrc.nisp.utils.EitherReads.eitherReads

import scala.concurrent.Future

trait StatePensionConnector extends BackendConnector {
  implicit val reads = eitherReads[StatePensionExclusion, StatePension]

  implicit val writes = Writes[Either[StatePensionExclusion, StatePension]] {
    case Left(exclusion) => Json.toJson(exclusion)
    case Right(statePension) => Json.toJson(statePension)
  }

  implicit val formats = Format[Either[StatePensionExclusion, StatePension]](reads, writes)

  val apiHeader = "Accept" -> "application/vnd.hmrc.1.0+json"

  def getStatePension(nino: Nino)(implicit hc: HeaderCarrier): Future[Either[StatePensionExclusion, StatePension]] = {
    val urlToRead = s"$serviceUrl/ni/$nino"
    val headerCarrier = hc.copy(extraHeaders = hc.extraHeaders :+ apiHeader)
    retrieveFromCache[Either[StatePensionExclusion, StatePension]](APIType.StatePension, urlToRead)(headerCarrier, formats)
  }
} 
Example 86
Source File: MockIdentityVerificationHttp.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.helpers

import org.mockito.ArgumentMatchers
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import play.api.http.Status
import play.api.libs.json.Json

import scala.concurrent.Future
import scala.io.Source
import uk.gov.hmrc.http.{ HttpGet, HttpResponse }

object MockIdentityVerificationHttp extends MockitoSugar {
  val mockHttp = mock[HttpGet]

  val possibleJournies = Map(
    "success-journey-id" -> "test/resources/identity-verification/success.json",
    "incomplete-journey-id" -> "test/resources/identity-verification/incomplete.json",
    "failed-matching-journey-id" -> "test/resources/identity-verification/failed-matching.json",
    "insufficient-evidence-journey-id" -> "test/resources/identity-verification/insufficient-evidence.json",
    "locked-out-journey-id" -> "test/resources/identity-verification/locked-out.json",
    "user-aborted-journey-id" -> "test/resources/identity-verification/user-aborted.json",
    "timeout-journey-id" -> "test/resources/identity-verification/timeout.json",
    "technical-issue-journey-id" -> "test/resources/identity-verification/technical-issue.json",
    "precondition-failed-journey-id" -> "test/resources/identity-verification/precondition-failed.json",
    "invalid-journey-id" -> "test/resources/identity-verification/invalid-result.json",
    "invalid-fields-journey-id" -> "test/resources/identity-verification/invalid-fields.json",
    "failed-iv-journey-id" -> "test/resources/identity-verification/failed-iv.json"
  )

  def mockJourneyId(journeyId: String): Unit = {
    val fileContents = Source.fromFile(possibleJournies(journeyId)).mkString
    when(mockHttp.GET[HttpResponse](ArgumentMatchers.contains(journeyId))(ArgumentMatchers.any(), ArgumentMatchers.any(),ArgumentMatchers.any())).
      thenReturn(Future.successful(HttpResponse(Status.OK, responseJson = Some(Json.parse(fileContents)))))
  }

  possibleJournies.keys.foreach(mockJourneyId)
} 
Example 87
Source File: MockSessionCache.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.helpers

import play.api.libs.json.{Json, Reads, Writes}
import uk.gov.hmrc.http.cache.client.{CacheMap, SessionCache}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ExecutionContext, Future}
import scala.io.Source
import uk.gov.hmrc.http.{HeaderCarrier, HttpDelete, HttpGet, HttpPut, UserId}

object MockSessionCache extends SessionCache{
  val cachedNinoAndUsername = TestAccountBuilder.cachedNino
  val cachedUserId = UserId(s"/auth/oid/$cachedNinoAndUsername")

  override def defaultSource: String = ???
  override def baseUri: String = ???
  override def domain: String = ???
  override def http: HttpGet with HttpPut with HttpDelete = ???

  private def loadObjectFromFile[T](filename: String)(implicit rds: Reads[T]): Option[T] = {
    val fileContents = Source.fromFile(filename).mkString
    Json.parse(fileContents).validate[T].fold(invalid => None, valid => Some(valid))
  }

  private def loadObjectBasedOnKey[T](key: String)(implicit rds: Reads[T]): Option[T] =
    key match {
      case _ => None
    }

  override def fetchAndGetEntry[T](key: String)(implicit hc: HeaderCarrier, rds: Reads[T],ec:ExecutionContext): Future[Option[T]] =
    Future.successful(hc.userId.filter(_ == cachedUserId).flatMap(p => loadObjectBasedOnKey(key)))

  override def cache[A](formId: String, body: A)(implicit wts: Writes[A], hc: HeaderCarrier,ec:ExecutionContext): Future[CacheMap] = Future.successful(CacheMap("", Map()))
} 
Example 88
Source File: CitizenDetailsResponseSpec.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.models

import org.joda.time.LocalDate
import play.api.libs.json.Json
import uk.gov.hmrc.nisp.helpers.TestAccountBuilder
import uk.gov.hmrc.nisp.models.citizen.{Address, Citizen, CitizenDetailsResponse}
import uk.gov.hmrc.play.test.UnitSpec


class CitizenDetailsResponseSpec extends UnitSpec {
    "Citizen" should {

      val nino = TestAccountBuilder.regularNino
      val citizenDetailsResponse = CitizenDetailsResponse(
        Citizen(
          nino,
          Some("AHMED"),
          Some("BRENNAN"),
          new LocalDate(1954, 3, 9)
        ),
        Some(Address(
          country = Some("USA")
        ))
      )

      "parse correctly when date of birth is a date" in {
        Json.parse(
          s"""
            |{
            |  "etag":"1",
            |  "person":{
            |    "sex":"M",
            |    "dateOfBirth":-499132800000,
            |    "nino":"$nino",
            |    "firstName":"AHMED",
            |    "middleName":"",
            |    "lastName":"BRENNAN",
            |    "title":"Mrs",
            |    "honours":null
            |  },
            |  "address":{
            |    "line1":"108 SAI ROAD",
            |    "line2":"",
            |    "line3":"",
            |    "line4":null,
            |    "postcode":"12345",
            |    "country":"USA",
            |    "startDate":1223510400000,
            |    "type":"Residential"
            |  }
            |}
          """.stripMargin
        ).as[CitizenDetailsResponse] shouldBe citizenDetailsResponse
      }

      "parse correctly when date of birth is a long" in {
        Json.parse(
          s"""
             |{
             |  "etag":"1",
             |  "person":{
             |    "sex":"M",
             |    "dateOfBirth":"1954-03-09",
             |    "nino":"$nino",
             |    "firstName":"AHMED",
             |    "middleName":"",
             |    "lastName":"BRENNAN",
             |    "title":"Mrs",
             |    "honours":null
             |  },
             |  "address":{
             |    "line1":"108 SAI ROAD",
             |    "line2":"",
             |    "line3":"",
             |    "line4":null,
             |    "postcode":"12345",
             |    "country":"USA",
             |    "startDate":1223510400000,
             |    "type":"Residential"
             |  }
             |}
          """.stripMargin
        ).as[CitizenDetailsResponse] shouldBe citizenDetailsResponse
      }
    }
} 
Example 89
Source File: SPExclusionSpec.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.models.enums

import Exclusion.Exclusion
import play.api.libs.json.{JsString, Json}
import uk.gov.hmrc.play.test.UnitSpec

class SPExclusionSpec extends UnitSpec {

  "SP Exclusion" when {
    "serialised into JSON" should {
      "output Dead when Dead is formatted" in {
        Json.toJson(Exclusion.Dead) shouldBe JsString("Dead")
      }

      "parse Dead when Dead is read" in {
        Json.fromJson[Exclusion](JsString("Dead")).get shouldBe Exclusion.Dead
      }
    }
  }
} 
Example 90
Source File: NpsDateSpec.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.models

import org.joda.time.LocalDate
import play.api.libs.json.{JsNull, JsString, Json}
import uk.gov.hmrc.nisp.utils.Constants
import uk.gov.hmrc.play.test.UnitSpec

class NpsDateSpec extends UnitSpec {
  "NpsDate" when {
    "JSON parsing" should {
      "return a JSError for null date" in {
        JsNull.validate[NpsDate].isError shouldBe true
      }
    }

    "JSON serialisation" should {
      "return JSString in correct format" in {
        Json.toJson(NpsDate(new LocalDate(2015,1,1))) shouldBe JsString("01/01/2015")
      }
      "deserialise works" in {
        Json.fromJson[NpsDate](JsString("01/01/2015")).get shouldBe NpsDate(new LocalDate(2015,1,1))
      }
    }

    "taxYearEndDate" should {
      "return tax year end date" in {
        NpsDate.taxYearEndDate(2015) shouldBe NpsDate(2016, Constants.taxYearsStartEndMonth, Constants.taxYearEndDay)
      }
    }

    "taxYearStartDate" should {
      "return tax year start date" in {
        NpsDate.taxYearStartDate(2015) shouldBe NpsDate(2015, Constants.taxYearsStartEndMonth, Constants.taxYearStartDay)
      }
    }
  }
} 
Example 91
Source File: BackendConnectorSpec.scala    From nisp-frontend   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.nisp.connectors

import org.mockito.Mockito.when
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.mock.MockitoSugar
import play.api.libs.json.Json
import uk.gov.hmrc.http.cache.client.SessionCache
import uk.gov.hmrc.nisp.helpers.{MockMetricsService, MockSessionCache}
import uk.gov.hmrc.nisp.models.NationalInsuranceRecord
import uk.gov.hmrc.nisp.models.enums.APIType
import uk.gov.hmrc.nisp.services.MetricsService
import uk.gov.hmrc.nisp.utils.JsonDepersonaliser
import uk.gov.hmrc.play.test.UnitSpec

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import uk.gov.hmrc.http.{HeaderCarrier, HttpGet, HttpResponse}

class BackendConnectorSpec extends UnitSpec with MockitoSugar with ScalaFutures {

  val mockHttp: HttpGet = mock[HttpGet]
  
  object BackendConnectorImpl extends BackendConnector {
    override def http: HttpGet = mockHttp
    override def sessionCache: SessionCache = MockSessionCache
    override def serviceUrl: String = "national-insurance"
    override val metricsService: MetricsService = MockMetricsService

    def getNationalInsurance()(implicit headerCarrier: HeaderCarrier): Future[NationalInsuranceRecord] = {
      val urlToRead = s"$serviceUrl/ni"
      retrieveFromCache[NationalInsuranceRecord](APIType.NationalInsurance, urlToRead)(headerCarrier, NationalInsuranceRecord.formats)
    }
  }

  implicit val headerCarrier = HeaderCarrier(extraHeaders = Seq("Accept" -> "application/vnd.hmrc.1.0+json"))

  "connectToMicroservice" should {
    "should return depersonalised JSON" in {
      val json = Json.obj(
        "qualifyingYearsPriorTo1975" -> 0,
        "numberOfGaps" -> 6,
        "numberOfGapsPayable" -> 4,
        "dateOfEntry" -> "1975-08-01",
        "homeResponsibilitiesProtection" -> false,
        "earningsIncludedUpTo" -> "2016-04-05",
        "_embedded" -> Json.obj(
          "taxYears" -> Json.arr()
        )
      )

      val depersonalisedJson =  JsonDepersonaliser.depersonalise(json) match {
        case Success(s) => s
        case Failure(_) => fail()
      }

      val Ok = 200
      val response = Future(HttpResponse(Ok, Option.apply(json)))
      when(mockHttp.GET[HttpResponse]("national-insurance/ni")).thenReturn(response)

      val future: Future[NationalInsuranceRecord] = BackendConnectorImpl.getNationalInsurance()

      whenReady(future.failed) {
        t: Throwable =>
          t.getMessage.contains(depersonalisedJson) shouldBe true
          t.getMessage.contains("2016-04-05") shouldBe false
      }
    }
  }

} 
Example 92
Source File: CatalogManagerClient.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package daf.catalogmanager

import java.net.URLEncoder
import java.security.AccessControlException

import it.gov.daf.common.config.Read
import json._
import org.slf4j.LoggerFactory
import play.api.Configuration
import play.api.libs.json.Json
import scalaj.http.{ Http, HttpResponse }

import scala.util.{ Failure, Try, Success => TrySuccess }

class CatalogManagerClient(serviceUrl: String) {

  val logger = LoggerFactory.getLogger("it.gov.daf.CatalogManager")

  private def callService(authorization: String, catalogId: String) = Try {
    Http(s"$serviceUrl/catalog-manager/v1/catalog-ds/get/${URLEncoder.encode(catalogId,"UTF-8")}")
      .header("Authorization", authorization)
      .asString
  }

  private def parseCatalog(response: HttpResponse[String]) =
    if (response.code == 401)  Failure { new AccessControlException("Unauthorized") }
    else if (response.isError) Failure { new RuntimeException(s"Error retrieving catalog data: [${response.code}] with body [${response.body}]") }
    else Try { Json.parse(response.body).as[MetaCatalog] }

  def getById(authorization: String, catalogId: String): Try[MetaCatalog] = for {
    response <- callService(authorization, catalogId)
    catalog  <- parseCatalog(response)
  } yield catalog

}

object CatalogManagerClient {

  def fromConfig(config: Configuration) = Read.string { "daf.catalog_url" }.!.read(config) match {
    case TrySuccess(baseUrl) => new CatalogManagerClient(baseUrl)
    case Failure(error)      => throw new RuntimeException("Unable to create catalog-manager client", error)
  }

} 
Example 93
Source File: KyloApiClient.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package it.gov.daf.securitymanager.service

import com.google.inject.Inject
import it.gov.daf.securitymanager.service.utilities.ConfigReader
import play.api.Logger
import play.api.libs.json.{JsUndefined, JsValue, Json}
import play.api.libs.ws.{WSAuthScheme, WSClient}
import security_manager.yaml.{Error, Success}

import scala.concurrent.Future

class KyloApiClient @Inject()(wSClient: WSClient){

  import play.api.libs.concurrent.Execution.Implicits._

  def createCategory(name: String):Future[Either[Error,Success]]= {

    val jsonRequest: JsValue = Json.parse(
                                        s"""{
                                           "id": null,
                                           "name": "$name",
                                           "description": null,
                                           "icon": null,
                                           "iconColor": null,
                                           "userFields": [],
                                           "userProperties": [],
                                           "relatedFeedSummaries": [],
                                           "securityGroups": [],
                                           "roleMemberships": [],
                                           "feedRoleMemberships": [],
                                           "owner": null,
                                           "systemName": "$name"
                                    }""")

    Logger.logger.debug("createCategory: "+ jsonRequest.toString())

    val response = wSClient.url(ConfigReader.kyloUrl + "/proxy/v1/feedmgr/categories")
                    .withHeaders("Accept" -> "application/json")
                    .withAuth(ConfigReader.kyloUser,ConfigReader.kyloUserPwd,WSAuthScheme.BASIC)
                    .post(jsonRequest)

    response.map{response =>

      if( response.status != 200 )
        Left( Error(Option(0),Some("Error in during kylo category creation: bad http code"+response.status),None) )
      else{
        Logger.logger.debug("RESPONSE:"+response.json)
        val result = response.json \ "id"
        if( result.isInstanceOf[JsUndefined] )
          Left( Error(Option(0),Some("Error in during kylo category creation"),None) )
        else
          Right( Success(Some("Category created"), Some("ok")) )
      }

    }

  }


} 
Example 94
Source File: TestJson.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package it.gov.daf.catalogmanager.repository.voc

import java.io.FileInputStream

import catalog_manager.yaml.KeyValue
import play.api.libs.json.{JsArray, JsValue}

object TestJson extends App {
  import play.api.libs.json.{JsError, JsResult, JsSuccess, Json}

  val stream = new FileInputStream("data/voc/cv_theme-subtheme_bk.json")
  val json = try { (Json.parse(stream) \ "voc").asOpt[JsArray]} finally {stream.close()}
  val dcatapitThemeId = "AGRI"
  val subthemeId = "policy"
  print {
    json match {
      case Some(s) => s.value.map(x => ((x \ "theme_code").as[String],
        (x \ "subthemes").as[List[JsValue]])).map{ x=>

        x._2.map{ y=> //subthemes

          (x._1, (y \ "subthemes_ita").as[List[List[String]]])
        }
      }.flatten
        .filter(x=>x._1.equals(dcatapitThemeId))
        .map{x=>
          println(x)
          x._2.map{y=>
            println(y)
            println(y.length)
            //println(y(0))
            //println(y(1))
            KeyValue(y(0), y(1))
          }
        }.flatMap(x=>x)
      case None =>
        println("VocRepositoryFile - Error occurred with Json")
        Seq()
    }
  }

} 
Example 95
Source File: CatalogControllersSpec.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
import java.io.IOException
import java.net.ServerSocket

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import catalog_manager.yaml.MetaCatalog
import org.specs2.mutable.Specification
import play.api.Application
import play.api.http.Status
import play.api.routing.Router
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.json.{JsArray, JsValue, Json}
import play.api.libs.ws.WSResponse
import play.api.libs.ws.ahc.AhcWSClient
import play.api.test._
import it.gov.daf.catalogmanager
import it.gov.daf.catalogmanager.client.Catalog_managerClient

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}


class CatalogControllersSpec extends Specification  {

  def application: Application = GuiceApplicationBuilder().build()

  import catalog_manager.yaml.BodyReads.MetaCatalogReads

  "The catalog-manager" should {
    "Call catalog-manager/v1/dataset-catalogs return ok status" in
      new WithServer(app = application, port = 9000) {
        WsTestClient.withClient { implicit client =>
          val response: WSResponse = Await.result[WSResponse](client.
            url(s"http://localhost:9001/catalog-manager/v1/dataset-catalogs").
            execute, Duration.Inf)
          println(response.status)
          response.status must be equalTo Status.OK
        }
      }

    "Call catalog-manager/v1/dataset-catalogs return a non empty list if" +
      "you have error maybe is necessaty to add data to db" in
      new WithServer(app = application, port = 9000) {
        WsTestClient.withClient { implicit client =>
          val response: WSResponse = Await.result[WSResponse](client.
            url(s"http://localhost:9001/catalog-manager/v1/dataset-catalogs").
            execute, Duration.Inf)
          println(response.status)
          println("ALE")
          println(response.body)
          val json: JsValue = Json.parse(response.body)
          json.as[JsArray].value.size must be greaterThan (0)
        }
      }


    "The catalog-manager" should {
      "Call catalog-manager/v1/dataset-catalogs/{logical_uri} return ok status" in
        new WithServer(app = application, port = 9000) {
          val logicalUri = "daf://dataset/std/standard/standard/uri_cultura/standard"
          val url = s"http://localhost:9001/catalog-manager/v1/dataset-catalogs/$logicalUri"
          println(url)
          WsTestClient.withClient { implicit client =>
            val response: WSResponse = Await.result[WSResponse](client.
              url(url).
              execute, Duration.Inf)
            println(response.status)
            response.status must be equalTo Status.OK
          }
        }
    }

    "The catalog-manager" should {
      "Call catalog-manager/v1/dataset-catalogs/{anything} return 401" in
        new WithServer(app = application, port = 9000) {
          val logicalUri = "anything"
          val url = s"http://localhost:9001/catalog-manager/v1/dataset-catalogs/$logicalUri"
          println(url)
          WsTestClient.withClient { implicit client =>
            val response: WSResponse = Await.result[WSResponse](client.
              url(url).
              execute, Duration.Inf)
            println(response.status)
            response.status must be equalTo 401
          }
        }
    }
  }
} 
Example 96
Source File: TotalTweetsScheduler.scala    From redrock   with Apache License 2.0 5 votes vote down vote up
package com.restapi

import java.io.{File, FileInputStream}

import akka.actor.{ActorRef, Actor, ActorSystem, Props}
import akka.io.IO
import org.slf4j.LoggerFactory
import play.api.libs.json.Json
import spray.can.Http
import akka.pattern.ask
import spray.http.DateTime
import scala.concurrent.duration._
import akka.util.Timeout
import scala.concurrent.ExecutionContext.Implicits.global
import org.apache.commons.codec.digest.DigestUtils
import scala.io.Source

case object GetTotalTweetsScheduler

object CurrentTotalTweets {
  @volatile
  var totalTweets: Long = 0
}

class ExecuterTotalTweetsES(delay: FiniteDuration, interval: FiniteDuration) extends Actor {
  context.system.scheduler.schedule(delay, interval) {
    getTotalTweetsES
  }

  val logger = LoggerFactory.getLogger(this.getClass)

  override def receive: Actor.Receive = {
    case GetTotalTweetsScheduler => {
      logger.info(s"Getting Total of Tweets. Begin: ${CurrentTotalTweets.totalTweets}")
    }
    case _ => // just ignore any messages
  }

  def getTotalTweetsES: Unit = {
    val elasticsearchRequests = new GetElasticsearchResponse(0, Array[String](), Array[String](),
      LoadConf.restConf.getString("searchParam.defaulStartDatetime"),
      LoadConf.restConf.getString("searchParam.defaultEndDatetime"),
      LoadConf.esConf.getString("decahoseIndexName"))
    val totalTweetsResponse = Json.parse(elasticsearchRequests.getTotalTweetsESResponse())
    logger.info(s"Getting Total of Tweets. Current: ${CurrentTotalTweets.totalTweets}")
    CurrentTotalTweets.totalTweets = (totalTweetsResponse \ "hits" \ "total").as[Long]
    logger.info(s"Total users updated. New: ${CurrentTotalTweets.totalTweets}")
  }
} 
Example 97
Source File: get_features_from_peinfo.scala    From gsoc_relationship   with Apache License 2.0 5 votes vote down vote up
import com.datastax.spark.connector._
import play.api.libs.json.Json
import play.api.libs.json._
import java.io.{ByteArrayOutputStream, ByteArrayInputStream}
import java.util.zip.{GZIPOutputStream, GZIPInputStream}
import Array.concat
import org.apache.spark.sql.types._
import org.apache.spark.ml.linalg.SQLDataTypes.VectorType 
import org.apache.spark.ml.linalg._
import org.apache.spark.sql.Row
import org.apache.spark.ml.feature.MinMaxScaler
import org.apache.spark.ml.linalg.DenseVector
import PreProcessingConfig._

case class peinfo_results_by_service_name_class(service_name: String, sha256: String)
case class peinfo_results_by_sha256_class(sha256: String, service_name: String, results: Array[Byte])
case class peinfo_join_results_class(sha256: String, service_name: String, results: String)
case class peinfo_int_final_array_rdd_class(sha256: String, array_results: Array[Double])
case class peinfo_binaray_final_array_rdd_class(sha256:String, array_results :Array[Double])
case class peinfo_final_array_rdd_class(sha256:String, array_results: Array[Double])

def unzip(x: Array[Byte]) : String = {      
    val inputStream = new GZIPInputStream(new ByteArrayInputStream(x))
    val output = scala.io.Source.fromInputStream(inputStream).mkString
    return output
}
def findAllIntinpeinfo( peinfo_json_results : JsLookupResult, time: Double): Array[Double]= {
    val entropy = peinfo_json_results \\ "entropy" ; val virt_address = peinfo_json_results \\ "virt_address"; val virt_size = peinfo_json_results \\ "virt_size"; val size = peinfo_json_results \\ "size";
    var i= 0; var List  = Array.iterate(0.0,17)(a=>a*0)
    for (k <- ( peinfo_json_results \\ "section_name")){
        k.as[String] match {
            case ".text\u0000\u0000\u0000" => { List(0)=entropy(i).as[Double]; List(1)=Integer.parseInt(virt_address(i).as[String].substring(2), 16).toDouble; List(2)=virt_size(i).as[Double]; List(3)=size(i).as[Double] }
            case ".data\u0000\u0000\u0000" => { List(4)=entropy(i).as[Double]; List(5)=Integer.parseInt(virt_address(i).as[String].substring(2), 16).toDouble; List(6)=virt_size(i).as[Double]; List(7)=size(i).as[Double] }
            case ".rsrc\u0000\u0000\u0000" => { List(8)=entropy(i).as[Double]; List(9)=Integer.parseInt(virt_address(i).as[String].substring(2), 16).toDouble; List(10)=virt_size(i).as[Double]; List(11)=size(i).as[Double] }
            case ".rdata\u0000\u0000" => { List(12)=entropy(i).as[Double]; List(13)=Integer.parseInt(virt_address(i).as[String].substring(2), 16).toDouble; List(14)=virt_size(i).as[Double]; List(15)=size(i).as[Double] }
            case other => {}
        }
        i = i + 1
    }
    List(16)= time
    return List.toArray
}

val peinfo_results_by_service_name_meta = sc.cassandraTable[peinfo_results_by_service_name_class](keyspace,service_name_table).where("service_name=?","peinfo")
val peinfo_results_by_service_name_rdd = peinfo_results_by_service_name_meta.keyBy(x=> (x.sha256,x.service_name))
val peinfo_results_by_sha256_meta = sc.cassandraTable[peinfo_results_by_sha256_class](keyspace,sha256_table)
val peinfo_results_by_sha256_rdd = peinfo_results_by_sha256_meta.keyBy(x => (x.sha256,x.service_name))
val peinfo_join_results = peinfo_results_by_service_name_rdd.join(peinfo_results_by_sha256_rdd).map(x=> (new peinfo_join_results_class(x._1._1,x._1._2, unzip(x._2._2.results)))).distinct().cache()

val peinfo_int_final_array_rdd = peinfo_join_results.map(x=>(x.sha256,(Json.parse(x.results) \ "pe_sections"),{if ((Json.parse(x.results) \ "timestamp").isInstanceOf[JsUndefined]) 0.0 else (Json.parse(x.results) \ "timestamp" \\ "timestamp")(0).as[Double]})).filter(x=> !x._2.isInstanceOf[JsUndefined]).map(x=>new  peinfo_int_final_array_rdd_class(x._1,findAllIntinpeinfo(x._2,x._3)))

val peinfo_dllfunction_list= peinfo_join_results.map(x=>Json.parse(x.results) \ "imports").filter(x=> !x.isInstanceOf[JsUndefined]).flatMap(x=>x.as[List[Map[String, String]]].map(x=>(x("dll")+"."+x("function")))).toDF("func_name").groupBy("func_name").count.sort(desc("count")).filter("count > 10000").rdd.map(r => r.getString(0)).collect().toList
implicit def bool2int(b:Boolean) = if (b) 1 else 0
def findAllBininpeinfo_dllfunction(peinfo_dllfunction : Seq[String]) : Array[Double] ={
    val forlist = for (family <- peinfo_dllfunction_list) yield {
        (peinfo_dllfunction.contains(family):Int).toDouble
    }
    return (forlist).toArray
}
val List502 = Array.iterate(0.0,502)(a=>0.0)
val peinfo_binaray_final_array_rdd = peinfo_join_results.map(x=>(x.sha256,(Json.parse(x.results) \ "imports"))).map(x=>new  peinfo_binaray_final_array_rdd_class(x._1,{if (x._2.isInstanceOf[JsUndefined]) List502 else findAllBininpeinfo_dllfunction(x._2.as[Seq[Map[String, String]]].map(x=>(x("dll")+"."+x("function"))))}))

val peinfo_int_final_array_rdd_before_join = peinfo_int_final_array_rdd.map(x=>(x.sha256,x.array_results))
val peinfo_binaray_final_array_rdd_before_join = peinfo_binaray_final_array_rdd.map(x=>(x.sha256,x.array_results))
val peinfo_array_rdd_by_join = peinfo_int_final_array_rdd_before_join.join(peinfo_binaray_final_array_rdd_before_join).map(x=> (x._1,concat(x._2._1,x._2._2)))
val peinfo_final_array_rdd = peinfo_array_rdd_by_join.map(x=>new peinfo_final_array_rdd_class(x._1,x._2))

val peinfo_schema = new StructType().add("sha256", StringType).add("peinfo",VectorType)
val peinfo_vector_rdd = peinfo_final_array_rdd.map(x=>(x.sha256,Vectors.dense(x.array_results)))
val peinfo_vector_rowrdd = peinfo_vector_rdd.map(p => Row(p._1,p._2))
val peinfo_vector_dataframe = spark.createDataFrame(peinfo_vector_rowrdd, peinfo_schema)
val peinfo_scaler = new MinMaxScaler()
  .setInputCol("peinfo")
  .setOutputCol("scaled_peinfo")
val peinfo_scalerModel = peinfo_scaler.fit(peinfo_vector_dataframe)
val peinfo_scaledData_df = peinfo_scalerModel.transform(peinfo_vector_dataframe)
val peinfo_scaledData_rdd = peinfo_scaledData_df.select("sha256","scaled_peinfo").rdd.map(row=>(row.getAs[String]("sha256"),row.getAs[DenseVector]("scaled_peinfo"))).map(x=>new peinfo_final_array_rdd_class(x._1,x._2.toArray))
peinfo_scaledData_rdd.toDF().write.format("parquet").save(peinfo_final_array_file) 
Example 98
Source File: get_features_from_objdump.scala    From gsoc_relationship   with Apache License 2.0 5 votes vote down vote up
import com.datastax.spark.connector._
import play.api.libs.json.Json
import play.api.libs.json._
import java.io.{ByteArrayOutputStream, ByteArrayInputStream}
import java.util.zip.{GZIPOutputStream, GZIPInputStream}
import PreProcessingConfig._

case class objdump_results_by_service_name_class(service_name: String, sha256: String)
case class objdump_results_by_sha256_class(sha256: String, service_name: String, results: Array[Byte])
case class objdump_join_results_class(sha256: String, service_name: String, results: String)
case class objdump_binaray_final_array_rdd_class(sha256: String, array_results: Array[Double])
 
val objdump_main_list = sc.textFile(objdump_x86Opcodes_file).collect.toList
def unzip(x: Array[Byte]) : String = {		
    val inputStream = new GZIPInputStream(new ByteArrayInputStream(x))
    val output = scala.io.Source.fromInputStream(inputStream).mkString
    return output
}
def combineAllObjdumpInOne( malwarelist :Seq[play.api.libs.json.JsValue]) : List[String] ={
    if (malwarelist(0).toString() == "null") return List("null")
    var begin = malwarelist(0).as[List[String]]
    for (i <- 1 to (malwarelist.size-1)){
        if (malwarelist(i).toString() == "null") begin = begin
        else begin = begin ::: malwarelist(i).as[List[String]]
    }
    return  begin
}
def convertToList( malwarelist :Seq[play.api.libs.json.JsValue]) : List[String] = {
    if (malwarelist(0).toString() == "null") return List("null")
    else {
        return malwarelist(0).as[List[String]]
    } 
    
}
def findAllBininobjdump_main_list(malware :List[String]) : Array[Double] ={
    if (malware == List("null")) return (List.fill(10000)(0.0)).toArray
    else {
        val forlist = for ( one  <- malware ) yield {
            objdump_main_list.indexOf(one) + 1.0
        }
        if (forlist.size < 10000){
            return  (List.concat(forlist,List.fill(10000-forlist.size)(0.0))).toArray
        }
        else return forlist.toArray
    }
}

val objdump_results_by_service_name_meta = sc.cassandraTable[objdump_results_by_service_name_class](keyspace,service_name_table).where("service_name=?","objdump")
val objdump_results_by_service_name_rdd = objdump_results_by_service_name_meta.keyBy(x=> (x.sha256,x.service_name))
val objdump_results_by_sha256_meta = sc.cassandraTable[objdump_results_by_sha256_class](keyspace,sha256_table)
val objdump_results_by_sha256_rdd = objdump_results_by_sha256_meta.keyBy(x => (x.sha256,x.service_name))
val objdump_join_results = objdump_results_by_service_name_rdd.join(objdump_results_by_sha256_rdd).map(x=> (new objdump_join_results_class(x._1._1,x._1._2, unzip(x._2._2.results)))).distinct()
val objdump_binaray_final_array_rdd = objdump_join_results.map(x=>(x.sha256,(Json.parse(x.results) \\ "opcodes"))).filter(x=> (x._2.size > 0)).map(x=>(x._1,if ( x._2.size == 1 ) convertToList(x._2) else combineAllObjdumpInOne(x._2))).map(x=>(x._1,findAllBininobjdump_main_list(x._2)))
objdump_binaray_final_array_rdd.toDF().write.format("parquet").save(objdump_binaray_final_array_file) 
Example 99
Source File: get_VT_signatures.scala    From gsoc_relationship   with Apache License 2.0 5 votes vote down vote up
import com.datastax.spark.connector._
import play.api.libs.json.Json
import java.io.{ByteArrayOutputStream, ByteArrayInputStream}
import java.util.zip.{GZIPOutputStream, GZIPInputStream}
import PreProcessingConfig._

case class VT_results_by_service_name_class(service_name: String, sha256: String)
case class VT_results_by_sha256_class(sha256: String, service_name: String, results: Array[Byte] )
case class VT_join_results_class(sha256: String, service_name: String, results: String)
case class VT_sample_signatures_initial_seq_rdd_class(sha256: String, seq_results: Seq[String])
case class VT_sample_signatures_final_array_rdd_class(sha256:String, array_results:Array[Double])

def unzip(x: Array[Byte]) : String = {		
    val inputStream = new GZIPInputStream(new ByteArrayInputStream(x))
    val output = scala.io.Source.fromInputStream(inputStream).mkString
    return output
}
def deleteNumberInSampleSignatures(x: String): Boolean = {
    val regex = "[0-9]".r
    return regex.findFirstIn(x).isEmpty
}

val VT_results_by_service_name_meta = sc.cassandraTable[VT_results_by_service_name_class](keyspace,service_name_table).where("service_name=?","virustotal")
val VT_results_by_service_name_rdd = VT_results_by_service_name_meta.keyBy(x=> (x.sha256,x.service_name))
val VT_results_by_sha256_meta = sc.cassandraTable[VT_results_by_sha256_class](keyspace,sha256_table)
val VT_results_by_sha256_rdd = VT_results_by_sha256_meta.keyBy(x => (x.sha256,x.service_name))
val VT_join_results = VT_results_by_service_name_rdd.join(VT_results_by_sha256_rdd).map(x => (new VT_join_results_class(x._1._1,x._1._2, unzip(x._2._2.results)))).distinct().cache()
val sample_signatures_rdd = VT_join_results.flatMap(x=>Json.parse(x.results) \ "scans" \\ "result").map(x=>Json.stringify(x)).filter( x=> !(x == "null"))
val sample_signatures_split_rdd = sample_signatures_rdd.flatMap(x=>x.replaceAll("""["]""","").replaceAll("""\![a-zA-Z0-9\s\+]+""","").replaceAll("""@[a-zA-Z0-9\s\+]+""","").replaceAll("""~[a-zA-Z0-9\s\+]+""","").replaceAll("""[\(|\[|{][a-zA-Z0-9\s\+]*[\)|\]|}]""","").replaceAll("""(\.|\!|\:|\_|\-|\\|/|\[|\])"""," ").split(" ")).filter(x=>(x.size>3)).filter(x=>deleteNumberInSampleSignatures(x)).map(x=>x.toLowerCase())
val signatures_prefix_rdd = sc.textFile(VT_signatures_prefix_suffix_file).map(x=>x.toLowerCase())
val family_signatures_subtract_rdd = sample_signatures_split_rdd.subtract(signatures_prefix_rdd)
val family_signatures_sorted_rdd = sc.parallelize(family_signatures_subtract_rdd.countByValue().toSeq).filter(x=>(x._2>50)).sortBy(x=>x._2,false)
val family_signatures_list = family_signatures_sorted_rdd.keys.collect().toList
val VT_sample_signatures_rdd = VT_join_results.map(x=>(x.sha256,(Json.parse(x.results) \ "scans" \\ "result").map(_.toString).filter( s => !(s== "null")).flatMap(x=>x.replaceAll("""["]""","").replaceAll("""\![a-zA-Z0-9\s\+]+""","").replaceAll("""@[a-zA-Z0-9\s\+]+""","").replaceAll("""~[a-zA-Z0-9\s\+]+""","").replaceAll("""[\(|\[|{][a-zA-Z0-9\s\+]*[\)|\]|}]""","").replaceAll("""(\.|\!|\:|\_|\-|\\|/|\[|\])"""," ").split(" ")).filter(x=>(x.size>3)).filter(x=>deleteNumberInSampleSignatures(x)).map(x=>x.toLowerCase())))
val  VT_sample_signatures_initial_seq_rdd = VT_sample_signatures_rdd.map(x=>new VT_sample_signatures_initial_seq_rdd_class(x._1, x._2))

implicit def bool2int(b:Boolean) = if (b) 1 else 0
def findAllInFamilySignatures(sample_signatures_seq : Seq[String]) : Array[Double] ={
    val forlist = for (family <- family_signatures_list) yield {
        (sample_signatures_seq.contains(family):Int).toDouble
    }
    return forlist.toArray
}

val VT_sample_signatures_final_array_rdd = VT_sample_signatures_initial_seq_rdd.map(x=>new VT_sample_signatures_final_array_rdd_class(x.sha256,findAllInFamilySignatures(x.seq_results)))
VT_sample_signatures_final_array_rdd.toDF().write.format("parquet").save(VT_sample_signatures_final_array_file) 
Example 100
Source File: HelperMethods.scala    From gsoc_relationship   with Apache License 2.0 5 votes vote down vote up
package com.holmesprocessing.analytics.relationship.knowledgeBase

import play.api.libs.json.Json
import java.util.zip.{GZIPOutputStream, GZIPInputStream}
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream


  def score(ruleset_1: String, ruleset_2:String) : Double = {

    val split_1 = ruleset_1.split(",").toSeq
    val split_2 = ruleset_2.split(",").toSeq
    if (split_1.length > 0 && split_2.length > 0) {
      return split_1.intersect(split_2).length.toDouble/split_1.union(split_2).distinct.length.toDouble
    } else {
      return 0
    }
  }

} 
Example 101
Source File: JsonReceiverActor.scala    From incubator-retired-iota   with Apache License 2.0 5 votes vote down vote up
package org.apache.iota.fey

import java.nio.file.Paths
import java.io.File

import akka.actor.{Actor, ActorLogging, ActorRef, Props}
import play.api.libs.json.{JsValue, Json}

class JsonReceiverActor extends Actor with ActorLogging {

  import JsonReceiverActor._

  val monitoring_actor = FEY_MONITOR.actorRef
  var watchFileTask: WatchServiceReceiver = _
  var watchThread: Thread = _

  override def preStart() {
    prepareDynamicJarRepo()
    processCheckpointFiles()

    watchFileTask = new WatchServiceReceiver(self)
    watchThread = new Thread(watchFileTask, GLOBAL_DEFINITIONS.WATCH_SERVICE_THREAD)

    monitoring_actor  ! Monitor.START(Utils.getTimestamp)
    watchThread.setDaemon(true)
    watchThread.start()

    watchFileTask.watch(Paths.get(CONFIG.JSON_REPOSITORY))
  }

  private def prepareDynamicJarRepo() = {
    val jarDir = new File(CONFIG.DYNAMIC_JAR_REPO)
    if (!jarDir.exists()){
      jarDir.mkdir()
    }else if(CONFIG.DYNAMIC_JAR_FORCE_PULL){
      jarDir.listFiles().foreach(_.delete())
    }
  }


  private def processCheckpointFiles() = {
    if (CONFIG.CHEKPOINT_ENABLED) {
      val checkpoint = new CheckpointProcessor(self)
      checkpoint.run()
    }
  }

  override def postStop() {
    monitoring_actor  ! Monitor.STOP(Utils.getTimestamp)
    watchThread.interrupt()
    watchThread.join()
  }

  override def postRestart(reason: Throwable): Unit = {
    monitoring_actor  ! Monitor.RESTART(reason, Utils.getTimestamp)
    preStart()
  }

  override def receive: Receive = {
    case JSON_RECEIVED(json, file) =>
      log.info(s"JSON RECEIVED => ${Json.stringify(json)}")
      context.parent ! FeyCore.ORCHESTRATION_RECEIVED(json, Some(file))

    case _ =>
  }

}

object JsonReceiverActor {

  case class JSON_RECEIVED(json: JsValue, file: File)

} 
Example 102
Source File: FeyUIService.scala    From incubator-retired-iota   with Apache License 2.0 5 votes vote down vote up
package org.apache.iota.fey

import org.apache.iota.fey.FeyCore.JSON_TREE
import play.api.BuiltInComponents
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc._
import play.api.routing.Router
import play.api.routing.sird._
import play.core.server._
import CONFIG._

import scala.concurrent.Future

object FeyUIService {


  val components = new FeyUIService(URL_PATH, PORT)
  val server = components.server
}

class FeyUIService(urlPath: String, port: Int) extends NettyServerComponents with BuiltInComponents {

  val THREAD_SLEEP_TIME = 2000
  lazy val router = Router.from {
    case GET(p"/fey/activeactors") => Action {
      FEY_CORE_ACTOR.actorRef ! JSON_TREE
      Thread.sleep(THREAD_SLEEP_TIME)
      val json = IdentifyFeyActors.generateTreeJson()
      val jsonTree: String = IdentifyFeyActors.getHTMLTree(json)
      Results.Ok(jsonTree).as("text/html")
    }
    case GET(p"/fey/actorslifecycle") => Action {
      val jsonTree = Json.stringify(Monitor.events.printWithEvents)
      Results.Ok(jsonTree).as("application/json")
    }
    case GET(p"/fey/monitoringevents") => Action {
      val returnValue: String = try {
        if (CONFIG.MONITORING_TYPE == "COMPLETE") {
          Monitor.getHTMLevents
        } else {
          Monitor.getSimpleHTMLEvents
        }
      } catch {
        case e: Exception => ""
      }
      Results.Ok(returnValue).as("text/html")
    }
  }

  override lazy val serverConfig = ServerConfig(
    port = Some(port),
    address = urlPath
  )
  override lazy val httpErrorHandler = new DefaultHttpErrorHandler(environment,
    configuration, sourceMapper, Some(router)) {

    override protected def onNotFound(request: RequestHeader, message: String) = {
      Future.successful(Results.NotFound("NO_DATA_FOUND"))
    }
  }
} 
Example 103
Source File: CheckpointProcessor.scala    From incubator-retired-iota   with Apache License 2.0 5 votes vote down vote up
package org.apache.iota.fey

import java.io.File

import akka.actor.ActorRef
import org.apache.iota.fey.JsonReceiverActor.JSON_RECEIVED
import play.api.libs.json.{JsValue, Json}

import scala.io.Source


class CheckpointProcessor(receiverActor: ActorRef) extends JsonReceiver{

  override def run(): Unit = {
    processCheckpointFiles()
  }

  def getJsonObject(params: String): Option[JsValue] = {
    try{
      val stringJson = Source.fromFile(params).getLines.mkString
      Option(Json.parse(stringJson))
    }catch{
      case e: Exception =>
        log.error("Could not parse JSON", e)
        None
    }
  }

  private def processJson(path: String, file: File) = {
    try{
      getJsonObject(path) match {
        case Some(orchestrationJSON) =>
          val valid = validJson(orchestrationJSON)
          if(valid && (orchestrationJSON \ JSON_PATH.COMMAND).as[String].toUpperCase != "DELETE"){
            checkForLocation(orchestrationJSON)
          }
          if(valid) {
            receiverActor ! JSON_RECEIVED(orchestrationJSON, file)
          }else{
            log.warn(s"File $path not processed. Incorrect JSON schema")
          }
          file.delete()
        case None =>
      }
    } catch {
      case e: Exception =>
        log.error(s"File $path will not be processed", e)
    }
  }

  private def processCheckpointFiles() = {
    Utils.getFilesInDirectory(CONFIG.CHECKPOINT_DIR)
      .filter(file => file.getName.endsWith(CONFIG.JSON_EXTENSION))
      .foreach(file => {
        processJson(file.getAbsolutePath, file)
      })
  }

  override def execute(): Unit = {}
  override def exceptionOnRun(e: Exception): Unit = {}
} 
Example 104
Source File: PredefinedTag.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models

import java.io.InputStream
import java.sql.Connection

import play.api.Logger
import play.api.libs.json.{Json, OFormat}

case class PredefinedTag(property: Option[String],
                         value: String,
                         solrIndexName: Option[String],
                         exported: Option[Boolean]) {

}

object PredefinedTag {

  val logger = Logger(getClass)

  implicit val jsonFormat: OFormat[PredefinedTag] = Json.format[PredefinedTag]

  def fromStream(stream: InputStream): Seq[PredefinedTag] = {
    try {
      Json.parse(stream).as[Seq[PredefinedTag]]
    } finally {
      stream.close()
    }
  }

  def updateInDB(predefinedTags: Seq[PredefinedTag])(implicit connection: Connection): (Seq[InputTagId], Seq[InputTag]) = {
    val indexIdsByName = SolrIndex.listAll.map(i => i.name -> i.id).toMap
    val tagsInDBByContent = InputTag.loadAll().map(t => t.tagContent -> t).toMap

    val newTags = predefinedTags.map { tag =>
      TagContent(tag.solrIndexName.flatMap(indexIdsByName.get), tag.property, tag.value) -> tag
    }.toMap

    val toDelete = tagsInDBByContent.filter { case (content, tag) => tag.predefined && !newTags.contains(content) }.map(_._2.id).toSeq
    val toInsert = newTags.filter(t => !tagsInDBByContent.contains(t._1)).map { case (tc, t) =>
      InputTag.create(tc.solrIndexId, t.property, t.value, t.exported.getOrElse(true), predefined = true)
    }.toSeq

    InputTag.insert(toInsert: _*)
    InputTag.deleteByIds(toDelete)
    if (toDelete.nonEmpty || toInsert.nonEmpty) {
      logger.info(s"Inserted ${toInsert.size} new predefined tags into the DB and deleted ${toDelete.size} no longer existing predefined tags.")
    }

    (toDelete, toInsert)
  }

} 
Example 105
Source File: SearchInputWithRules.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models

import java.sql.Connection
import models.rules._
import play.api.libs.json.{Json, OFormat}

case class SearchInputWithRules(id: SearchInputId,
                                term: String,
                                synonymRules: List[SynonymRule] = Nil,
                                upDownRules: List[UpDownRule] = Nil,
                                filterRules: List[FilterRule] = Nil,
                                deleteRules: List[DeleteRule] = Nil,
                                redirectRules: List[RedirectRule] = Nil,
                                tags: Seq[InputTag] = Seq.empty,
                                isActive: Boolean,
                                comment: String) {

  lazy val trimmedTerm: String = term.trim()

  def allRules: List[Rule] = {
    synonymRules ++ upDownRules ++ filterRules ++ deleteRules ++ redirectRules
  }

  def hasAnyActiveRules: Boolean = {
    allRules.exists(r => r.isActive)
  }

}

object SearchInputWithRules {

  implicit val jsonFormat: OFormat[SearchInputWithRules] = Json.format[SearchInputWithRules]

  def loadById(id: SearchInputId)(implicit connection: Connection): Option[SearchInputWithRules] = {
    SearchInput.loadById(id).map { input =>
      SearchInputWithRules(input.id, input.term,
        synonymRules = SynonymRule.loadByInputId(id),
        upDownRules = UpDownRule.loadByInputId(id),
        filterRules = FilterRule.loadByInputId(id),
        deleteRules = DeleteRule.loadByInputId(id),
        redirectRules = RedirectRule.loadByInputId(id),
        tags = TagInputAssociation.loadTagsBySearchInputId(id),
        isActive = input.isActive,
        comment = input.comment)
    }
  }

  
  def loadWithUndirectedSynonymsAndTagsForSolrIndexId(solrIndexId: SolrIndexId)(implicit connection: Connection): List[SearchInputWithRules] = {
    val inputs = SearchInput.loadAllForIndex(solrIndexId)
    val rules = SynonymRule.loadUndirectedBySearchInputIds(inputs.map(_.id))
    val tags = TagInputAssociation.loadTagsBySearchInputIds(inputs.map(_.id))

    inputs.map { input =>
      SearchInputWithRules(input.id, input.term,
        synonymRules = rules.getOrElse(input.id, Nil).toList,
        tags = tags.getOrElse(input.id, Seq.empty),
        isActive = input.isActive,
        comment = input.comment) // TODO consider only transferring "hasComment" for list overview
    }
  }

  def update(searchInput: SearchInputWithRules)(implicit connection: Connection): Unit = {
    SearchInput.update(searchInput.id, searchInput.term, searchInput.isActive, searchInput.comment)

    SynonymRule.updateForSearchInput(searchInput.id, searchInput.synonymRules)
    UpDownRule.updateForSearchInput(searchInput.id, searchInput.upDownRules)
    FilterRule.updateForSearchInput(searchInput.id, searchInput.filterRules)
    DeleteRule.updateForSearchInput(searchInput.id, searchInput.deleteRules)
    RedirectRule.updateForSearchInput(searchInput.id, searchInput.redirectRules)

    TagInputAssociation.updateTagsForSearchInput(searchInput.id, searchInput.tags.map(_.id))
  }

  def delete(id: SearchInputId)(implicit connection: Connection): Int = {
    val deleted = SearchInput.delete(id)
    if (deleted > 0) {
      for (rule <- Rule.allRules) {
        rule.deleteBySearchInput(id)
      }
      TagInputAssociation.deleteBySearchInputId(id)
    }
    deleted
  }

} 
Example 106
Source File: SuggestedSolrField.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models

import java.sql.Connection
import java.time.LocalDateTime

import anorm.SqlParser.get
import anorm._
import play.api.libs.json.{Json, OFormat}

class SuggestedSolrFieldId(id: String) extends Id(id)
object SuggestedSolrFieldId extends IdObject[SuggestedSolrFieldId](new SuggestedSolrFieldId(_))


case class SuggestedSolrField(id: SuggestedSolrFieldId = SuggestedSolrFieldId(),
                         name: String) {

}

object SuggestedSolrField {

  implicit val jsonFormat: OFormat[SuggestedSolrField] = Json.format[SuggestedSolrField]

  val TABLE_NAME = "suggested_solr_field"
  val ID = "id"
  val NAME = "name"
  val SOLR_INDEX_ID = "solr_index_id"
  val LAST_UPDATE = "last_update"

  val sqlParser: RowParser[SuggestedSolrField] = {
    get[SuggestedSolrFieldId](s"$TABLE_NAME.$ID") ~
      get[String](s"$TABLE_NAME.$NAME") map { case id ~ name =>
      SuggestedSolrField(id, name)
    }
  }

  def listAll(solrIndexId: SolrIndexId)(implicit connection: Connection): List[SuggestedSolrField] = {
    SQL"select * from #$TABLE_NAME where #$SOLR_INDEX_ID = $solrIndexId order by #$NAME asc".as(sqlParser.*)
  }

  def insert(solrIndexId: SolrIndexId, fieldName: String)(implicit connection: Connection): SuggestedSolrField = {
    val field = SuggestedSolrField(SuggestedSolrFieldId(), fieldName)
    SQL(s"insert into $TABLE_NAME($ID, $NAME, $SOLR_INDEX_ID, $LAST_UPDATE) values ({$ID}, {$NAME}, {$SOLR_INDEX_ID}, {$LAST_UPDATE})")
      .on(
        ID -> field.id,
        NAME -> fieldName,
        SOLR_INDEX_ID -> solrIndexId,
        LAST_UPDATE -> LocalDateTime.now()
      )
      .execute()
    field
  }


} 
Example 107
Source File: UpDownRule.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models.rules

import anorm.SqlParser.get
import anorm.{NamedParameter, RowParser, ~}
import models.{Id, IdObject, SearchInputId}
import play.api.libs.json.{Json, OFormat}

class UpDownRuleId(id: String) extends Id(id)
object UpDownRuleId extends IdObject[UpDownRuleId](new UpDownRuleId(_))


case class UpDownRule(id: UpDownRuleId = UpDownRuleId(),
                      upDownType: Int,
                      boostMalusValue: Int,
                      term: String,
                      isActive: Boolean) extends RuleWithTerm {

  override def toNamedParameters(searchInputId: SearchInputId): Seq[NamedParameter] = {
    super.toNamedParameters(searchInputId) ++ Seq[NamedParameter](
      UpDownRule.BOOST_MALUS_VALUE -> boostMalusValue,
      UpDownRule.UP_DOWN_TYPE -> upDownType
    )
  }
}

object UpDownRule extends RuleObjectWithTerm[UpDownRule] {

  val TABLE_NAME = "up_down_rule"

  val UP_DOWN_TYPE = "up_down_type"
  val BOOST_MALUS_VALUE = "boost_malus_value"

  val TYPE_UP = 0
  val TYPE_DOWN = 1

  override def fieldNames: Seq[String] = super.fieldNames ++ Seq(BOOST_MALUS_VALUE, UP_DOWN_TYPE)

  implicit val jsonFormat: OFormat[UpDownRule] = Json.format[UpDownRule]

  val sqlParser: RowParser[UpDownRule] = {
    get[UpDownRuleId](s"$TABLE_NAME.$ID") ~
      get[Int](s"$TABLE_NAME.$UP_DOWN_TYPE") ~
      get[Int](s"$TABLE_NAME.$BOOST_MALUS_VALUE") ~
      get[String](s"$TABLE_NAME.$TERM") ~
      get[Int](s"$TABLE_NAME.$STATUS") map { case id ~ upDownType ~ boostMalusValue ~ term ~ status =>
      UpDownRule(id, upDownType, boostMalusValue, term, isActiveFromStatus(status))
    }
  }

} 
Example 108
Source File: DeleteRule.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models.rules

import anorm.SqlParser.get
import anorm.{RowParser, ~}
import models.{Id, IdObject}
import play.api.libs.json.{Json, OFormat}

class DeleteRuleId(id: String) extends Id(id)
object DeleteRuleId extends IdObject[DeleteRuleId](new DeleteRuleId(_))


case class DeleteRule(id: DeleteRuleId = DeleteRuleId(),
                      term: String,
                      isActive: Boolean) extends RuleWithTerm {

}

object DeleteRule extends RuleObjectWithTerm[DeleteRule] {

  val TABLE_NAME = "delete_rule"

  implicit val jsonFormat: OFormat[DeleteRule] = Json.format[DeleteRule]

  override val sqlParser: RowParser[DeleteRule] = {
    get[DeleteRuleId](s"$TABLE_NAME.$ID") ~
      get[String](s"$TABLE_NAME.$TERM") ~
      get[Int](s"$TABLE_NAME.$STATUS") map { case id ~ term ~ status =>
      DeleteRule(id, term, isActiveFromStatus(status))
    }
  }
} 
Example 109
Source File: SynonymRule.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models.rules

import java.sql.Connection

import anorm.SqlParser.get
import anorm._
import models.{Id, IdObject, SearchInputId}
import play.api.libs.json.{Json, OFormat}

class SynonymRuleId(id: String) extends Id(id)
object SynonymRuleId extends IdObject[SynonymRuleId](new SynonymRuleId(_))

case class SynonymRule(id: SynonymRuleId = SynonymRuleId(),
                       synonymType: Int,
                       term: String,
                       isActive: Boolean) extends RuleWithTerm {

  override def toNamedParameters(searchInputId: SearchInputId): Seq[NamedParameter] = {
    super.toNamedParameters(searchInputId) ++ Seq[NamedParameter](
      SynonymRule.TYPE -> synonymType
    )
  }
}

object SynonymRule extends RuleObjectWithTerm[SynonymRule] {

  val TABLE_NAME = "synonym_rule"
  val TYPE = "synonym_type"

  val TYPE_UNDIRECTED = 0
  val TYPE_DIRECTED = 1

  implicit val jsonFormat: OFormat[SynonymRule] = Json.format[SynonymRule]

  override def fieldNames: Seq[String] = super.fieldNames :+ TYPE

  val sqlParser: RowParser[SynonymRule] = {
    get[SynonymRuleId](s"$TABLE_NAME.$ID") ~
      get[Int](s"$TABLE_NAME.$TYPE") ~
      get[String](s"$TABLE_NAME.$TERM") ~
      get[Int](s"$TABLE_NAME.$STATUS") map { case id ~ synonymType ~ term ~ status =>
        SynonymRule(id, synonymType, term, isActiveFromStatus(status))
    }
  }

  def loadUndirectedBySearchInputIds(ids: Seq[SearchInputId])(implicit connection: Connection): Map[SearchInputId, Seq[SynonymRule]] = {
    ids.grouped(100).toSeq.flatMap { idGroup =>
      SQL"select * from #$TABLE_NAME where #$TYPE = #$TYPE_UNDIRECTED AND #$SEARCH_INPUT_ID in ($idGroup)".as((sqlParser ~ get[SearchInputId](SEARCH_INPUT_ID)).*).map { case rule ~ id =>
        id -> rule
      }
    }.groupBy(_._1).mapValues(_.map(_._2))
  }

} 
Example 110
Source File: RedirectRule.scala    From smui   with Apache License 2.0 5 votes vote down vote up
package models.rules

import anorm.SqlParser.get
import anorm.{NamedParameter, RowParser, ~}
import models.{Id, IdObject, SearchInputId}
import play.api.libs.json.{Json, OFormat}

class RedirectRuleId(id: String) extends Id(id)
object RedirectRuleId extends IdObject[RedirectRuleId](new RedirectRuleId(_))


case class RedirectRule(id: RedirectRuleId = RedirectRuleId(),
                        target: String,
                        isActive: Boolean) extends Rule {

  override def toNamedParameters(searchInputId: SearchInputId): Seq[NamedParameter] = {
    super.toNamedParameters(searchInputId) ++ Seq[NamedParameter](
      RedirectRule.TARGET -> target
    )
  }
}

object RedirectRule extends RuleObject[RedirectRule] {

  val TABLE_NAME = "redirect_rule"
  val TARGET = "target"

  implicit val jsonFormat: OFormat[RedirectRule] = Json.format[RedirectRule]

  override def fieldNames: Seq[String] = super.fieldNames :+ TARGET

  override def orderByField: String = TARGET

  override val sqlParser: RowParser[RedirectRule] = {
    get[RedirectRuleId](s"$TABLE_NAME.$ID") ~
      get[String](s"$TABLE_NAME.$TARGET") ~
      get[Int](s"$TABLE_NAME.$STATUS") map { case id ~ target ~ status =>
      RedirectRule(id, target, isActiveFromStatus(status))
    }
  }

} 
Example 111
Source File: JsonRequestSpec.scala    From play-ws   with Apache License 2.0 5 votes vote down vote up
package play.api.libs.ws.ahc

import java.nio.charset.StandardCharsets

import akka.actor.ActorSystem
import akka.stream.Materializer
import akka.util.ByteString
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.when
import org.specs2.mock.Mockito

import org.specs2.mutable.Specification
import org.specs2.specification.AfterAll
import play.api.libs.json.JsString
import play.api.libs.json.JsValue
import play.api.libs.json.Json
import play.api.libs.ws.JsonBodyReadables
import play.api.libs.ws.JsonBodyWritables
import play.libs.ws.DefaultObjectMapper
import play.shaded.ahc.org.asynchttpclient.Response

import scala.io.Codec


class JsonRequestSpec extends Specification with Mockito with AfterAll with JsonBodyWritables {
  sequential

  implicit val system       = ActorSystem()
  implicit val materializer = Materializer.matFromSystem

  override def afterAll: Unit = {
    system.terminate()
  }

  "set a json node" in {
    val jsValue = Json.obj("k1" -> JsString("v1"))
    val client  = mock[StandaloneAhcWSClient]
    val req = new StandaloneAhcWSRequest(client, "http://playframework.com/", null)
      .withBody(jsValue)
      .asInstanceOf[StandaloneAhcWSRequest]
      .buildRequest()

    req.getHeaders.get("Content-Type") must be_==("application/json")
    ByteString.fromArray(req.getByteData).utf8String must be_==("""{"k1":"v1"}""")
  }

  "set a json node using the default object mapper" in {
    val objectMapper = DefaultObjectMapper.instance

    implicit val jsonReadable = body(objectMapper)
    val jsonNode              = objectMapper.readTree("""{"k1":"v1"}""")
    val client                = mock[StandaloneAhcWSClient]
    val req = new StandaloneAhcWSRequest(client, "http://playframework.com/", null)
      .withBody(jsonNode)
      .asInstanceOf[StandaloneAhcWSRequest]
      .buildRequest()

    req.getHeaders.get("Content-Type") must be_==("application/json")
    ByteString.fromArray(req.getByteData).utf8String must be_==("""{"k1":"v1"}""")
  }

  "read an encoding of UTF-8" in {
    val json = io.Source.fromResource("test.json")(Codec.ISO8859).getLines.mkString

    val ahcResponse = mock[Response]
    val response    = new StandaloneAhcWSResponse(ahcResponse)

    when(ahcResponse.getResponseBody(StandardCharsets.UTF_8)).thenReturn(json)
    when(ahcResponse.getContentType).thenReturn("application/json")

    val value: JsValue = JsonBodyReadables.readableAsJson.transform(response)
    verify(ahcResponse, times(1)).getResponseBody(StandardCharsets.UTF_8)
    verify(ahcResponse, times(1)).getContentType
    value.toString must beEqualTo(json)
  }

  "read an encoding of ISO-8859-1" in {
    val json = io.Source.fromResource("test.json")(Codec.ISO8859).getLines.mkString

    val ahcResponse = mock[Response]
    val response    = new StandaloneAhcWSResponse(ahcResponse)

    when(ahcResponse.getResponseBody(StandardCharsets.ISO_8859_1)).thenReturn(json)
    when(ahcResponse.getContentType).thenReturn("application/json;charset=iso-8859-1")

    val value: JsValue = JsonBodyReadables.readableAsJson.transform(response)
    verify(ahcResponse, times(1)).getResponseBody(StandardCharsets.ISO_8859_1)
    verify(ahcResponse, times(1)).getContentType
    value.toString must beEqualTo(json)
  }
} 
Example 112
Source File: JsonBodyWritables.scala    From play-ws   with Apache License 2.0 5 votes vote down vote up
package play.api.libs.ws

import akka.util.ByteString
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import play.api.libs.json.JsValue
import play.api.libs.json.Json

trait JsonBodyWritables {

  
  implicit val writeableOf_JsValue: BodyWritable[JsValue] = {
    BodyWritable(a => InMemoryBody(ByteString.fromArrayUnsafe(Json.toBytes(a))), "application/json")
  }

  def body(objectMapper: ObjectMapper): BodyWritable[JsonNode] =
    BodyWritable(
      json => InMemoryBody(ByteString.fromArrayUnsafe(objectMapper.writer.writeValueAsBytes(json))),
      "application/json"
    )
}

object JsonBodyWritables extends JsonBodyWritables 
Example 113
Source File: Bencharts.scala    From collection-strawman   with Apache License 2.0 5 votes vote down vote up
package strawman.collection

import javax.imageio.ImageIO

import org.jfree.chart.JFreeChart
import org.jfree.chart.axis.{LogAxis, LogarithmicAxis, NumberAxis}
import org.jfree.chart.plot.XYPlot
import org.jfree.chart.renderer.xy.XYErrorRenderer
import org.jfree.data.xy.{YIntervalSeries, YIntervalSeriesCollection}
import play.api.libs.json.{JsObject, Json}
import sbt._

object Bencharts {

  
  def apply(jmhReport: File, yAxisTitle: String, targetDir: File): Unit = {
    val json = Json.parse(IO.read(jmhReport))

    json.as[List[JsObject]]
      .groupBy { result =>
        val name = (result \ "benchmark").as[String]
        val benchmark = name.reverse.takeWhile(_ != '.').reverse
        benchmark // Benchmark name (e.g. "cons", "foreach", "map")
      }
      .foreach { case (benchmark, results) =>
        val seriess =
          results
            // group by concrete collection type
            .groupBy(result => (result \ "benchmark").as[String].stripSuffix(benchmark))
            .map { case (collectionType, iterations) =>
              val ySeries = new YIntervalSeries(collectionType)
              // each benchmark has been run with several collection sizes (8, 64, 512, etc.)
              // we add a point for each of these iterations
              for (iteration <- iterations) {
                ySeries.add(
                  (iteration \ "params" \ "size").as[String].toDouble,
                  (iteration \ "primaryMetric" \ "score").as[Double],
                  (iteration \ "primaryMetric" \ "scoreConfidence").apply(0).as[Double],
                  (iteration \ "primaryMetric" \ "scoreConfidence").apply(1).as[Double]
                )
              }
              ySeries
            }

        val xAxis = new LogarithmicAxis("Size")
        xAxis.setAllowNegativesFlag(true)
        val yAxis = new LogarithmicAxis(yAxisTitle)
        yAxis.setAllowNegativesFlag(true)

        val col = new YIntervalSeriesCollection()
        val renderer = new XYErrorRenderer
        for ((series, i) <- seriess.zipWithIndex) {
          col.addSeries(series)
          renderer.setSeriesLinesVisible(i, true)
        }

        val plot = new XYPlot(
          col,
          xAxis, yAxis,
          renderer
        )

        val chart = new JFreeChart(
          benchmark,
          JFreeChart.DEFAULT_TITLE_FONT,
          plot,
          true
        )

        ImageIO.write(
          chart.createBufferedImage(800, 600),
          "png",
          targetDir / s"$benchmark.png"
        )

      }
  }

} 
Example 114
Source File: JsonImplicitsSpec.scala    From play-json-ops   with MIT License 5 votes vote down vote up
package play.api.libs.json.ops.v4

import org.scalacheck.{Arbitrary, Gen, Shrink}
import org.scalacheck.ops._
import org.scalatest.freespec.AnyFreeSpec
import play.api.libs.json.{Format, Json}
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks._

case class KeyWrapper(key: String)
object KeyWrapper {
  implicit val arbKeyWrapper: Arbitrary[KeyWrapper] = Arbitrary(Gen.string.map(KeyWrapper(_)))
  implicit val shrinkKeyWrapper: Shrink[KeyWrapper] = Shrink { k =>
    Shrink.shrinkString.shrink(k.key).map(KeyWrapper(_))
  }

  implicit lazy val format: Format[KeyWrapper] = Format.asString(convertFromString, _.key)
  implicit val writeKey: WritesKey[KeyWrapper] = WritesKey(_.key)
  implicit val readKey: ReadsKey[KeyWrapper] = ReadsKey.of[String].map(KeyWrapper(_))
  implicit lazy val convertFromString: String => KeyWrapper = KeyWrapper(_)
}

class JsonImplicitsSpec extends AnyFreeSpec {

  private val exampleJson = Json.obj(
    "A" -> "value",
    "B" -> "other"
  )

  private val exampleMap = Map(
    KeyWrapper("A") -> "value",
    KeyWrapper("B") -> "other"
  )

  private val exampleMapFormat = Format.of[Map[KeyWrapper, String]]

  "explicit call to write should format the Json correctly" in {
    assertResult(exampleJson) {
      exampleMapFormat.writes(exampleMap)
    }
  }

  "explicit call to read should read correctly formatted Json" in {
    assertResult(exampleMap) {
      exampleMapFormat.reads(exampleJson).recoverTotal { err =>
        throw InvalidJsonException[Map[KeyWrapper, String]](exampleJson, err)
      }
    }
  }

  "formatter should read every value it writes and write it out the same way" in {
    forAll { value: Map[String, String] =>
      val keyWrappedMap = value.map {
        case (k, v) => (KeyWrapper(k), v)
      }
      val json = exampleMapFormat.writes(keyWrappedMap)
      val parsedMap = exampleMapFormat.reads(json).recoverTotal { err =>
        throw InvalidJsonException[Map[KeyWrapper, String]](json, err)
      }
      assertResult(keyWrappedMap)(parsedMap)
    }
  }
} 
Example 115
Source File: UTCFormatSpec.scala    From play-json-ops   with MIT License 5 votes vote down vote up
package play.api.libs.json.ops.v4

import org.joda.time.{DateTime, DateTimeZone}
import org.scalatest.WordSpec
import play.api.libs.json.{Format, Json}

case class NotUTC(when: DateTime)
object NotUTC {
  implicit val format: Format[NotUTC] = Json.format[NotUTC]
}

case class UseUTC(when: DateTime)
object UseUTC extends UTCFormats {
  implicit val format: Format[UseUTC] = Json.format[UseUTC]
}

class UTCFormatSpec extends WordSpec {

  private[this] val pacificTimeZone = DateTimeZone.forID("US/Pacific")

  "Json.format by default" should {
    "deserialize with the current time zone" in {
      val dt = new DateTime(pacificTimeZone)
      assertResult(DateTimeZone.getDefault) {
        val notUTC = Json.toJson(NotUTC(dt)).as[NotUTC]
        notUTC.when.getZone
      }
    }
  }

  "UTCFormats" should {

    "override the standard Format[DateTime]" in {
      val dt = new DateTime(pacificTimeZone)
      assertResult(DateTimeZone.UTC) {
        val useUTC = Json.toJson(UseUTC(dt)).as[UseUTC]
        useUTC.when.getZone
      }
    }
  }
} 
Example 116
Source File: ContributionSpec.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.contribution

import java.util.UUID
import services.ContentType
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import org.joda.time.{ DateTime, DateTimeZone }
import org.joda.time.format.DateTimeFormat
import play.api.libs.json.Json
import play.api.test._
import play.api.test.Helpers._
import scala.io.Source

@RunWith(classOf[JUnitRunner])
class ContributionSpec extends Specification {
  
  private val DATE_TIME_PATTERN = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ")
  private val madeAt = DateTime.parse("2016-06-03T13:02:00Z", DATE_TIME_PATTERN).withZone(DateTimeZone.UTC)

  "The sample Contribution" should {
    
    "be properly created from JSON" in {
      val json = Source.fromFile("test/resources/services/contribution/contribution.json").getLines().mkString("\n")
      val result = Json.fromJson[Contribution](Json.parse(json))
            
      // Parsed without errors?
      result.isSuccess must equalTo(true) 
      
      val contribution = result.get
      contribution.action must equalTo(ContributionAction.CONFIRM_BODY)
      contribution.madeBy must equalTo("rainer")
      contribution.madeAt must equalTo(madeAt)
      
      val item = contribution.affectsItem
      item.itemType must equalTo(ItemType.PLACE_BODY)
      item.documentId must equalTo("98muze1cl3saib")
      item.documentOwner must equalTo("rainer")
      item.filepartId must equalTo(Some(UUID.fromString("a7126845-16ac-434b-99bd-0f297e227822")))
      item.contentType must equalTo(Some(ContentType.TEXT_PLAIN))
      item.annotationId must equalTo(Some(UUID.fromString("7cfa1504-26de-45ef-a590-8b60ea8a60e8")))
      item.annotationVersionId must equalTo(Some(UUID.fromString("e868423f-5ea9-42ed-bb7d-5e1fac9195a0")))
      
      contribution.affectsUsers must equalTo(Seq("otheruser"))
    }
    
  }
  
  "JSON serialization/parsing roundtrip" should {
    
    "yield an equal Contribution" in {
      val contribution = Contribution(
        ContributionAction.DELETE_BODY,
        "rainer",
        madeAt,
        Item(
          ItemType.COMMENT_BODY,
          "98muze1cl3saib",
          "rainer",
          Some(UUID.fromString("7ccbf5dd-335b-4d59-bff6-d8d59d977825")),
          Some(ContentType.TEXT_TEIXML),
          Some(UUID.fromString("7cfa1504-26de-45ef-a590-8b60ea8a60e8")),
          Some(UUID.fromString("e868423f-5ea9-42ed-bb7d-5e1fac9195a0")),
          Some("just a comment"),
          None
        ),
        Seq("rainer"),
        None)
        
      // Convert to JSON
      val serialized = Json.prettyPrint(Json.toJson(contribution))
      
      val parseResult = Json.fromJson[Contribution](Json.parse(serialized))
      parseResult.isSuccess must equalTo(true)
      parseResult.get must equalTo(contribution)
    }
    
  }
  
} 
Example 117
Source File: RelationSpec.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.annotation.relation

import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.format.DateTimeFormat
import org.junit.runner._
import org.specs2.mutable._
import org.specs2.runner._
import play.api.test._
import play.api.test.Helpers._
import play.api.libs.json.Json
import scala.io.Source
import services.annotation.{Annotation, AnnotationBody}

@RunWith(classOf[JUnitRunner])
class RelationSpec extends Specification {
  
  private val DATE_TIME_PATTERN = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ")
  
  import services.annotation.BackendAnnotation._
  
  "The sample annotation" should {
  
    "be properly created from JSON" in {
      val json = Source.fromFile("test/resources/services/annotation/annotation-with-relation.json").getLines().mkString("\n")
      val result = Json.fromJson[Annotation](Json.parse(json))
      
      result.isSuccess must equalTo(true) 
      
      val relations = result.get.relations
      relations.size must equalTo(1)
      relations.head.bodies.size must equalTo(1)
      
      val body = relations.head.bodies.head
      body.hasType must equalTo(AnnotationBody.TAG)
      body.lastModifiedBy must equalTo(Some("rainer"))
      body.lastModifiedAt must equalTo(DateTime.parse("2018-05-07T15:31:00Z", DATE_TIME_PATTERN).withZone(DateTimeZone.UTC))
      body.value must equalTo("flyingTo")
    }
    
  }
  
} 
Example 118
Source File: HasAnnotationIndexingSpec.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.annotation

import java.util.UUID
import org.junit.runner._
import org.specs2.mutable._
import org.specs2.runner._
import play.api.test._
import play.api.test.Helpers._
import play.api.libs.json.Json
import scala.io.Source

@RunWith(classOf[JUnitRunner])
class HasAnnotationIndexingSpec extends Specification with HasAnnotationIndexing {
  
  import services.annotation.BackendAnnotation._
  
  "The helper" should {
    
    "properly remove relations" in {
      val json = Source.fromFile("test/resources/services/annotation/annotation-with-relation.json").getLines().mkString("\n")
      val result = Json.fromJson[Annotation](Json.parse(json))
      
      val annotation = result.get
      annotation.relations.size must equalTo(1)
      
      val unchanged = removeRelationsTo(annotation, UUID.randomUUID)
      unchanged.relations.size must equalTo(1)
      unchanged.relations must equalTo(annotation.relations)
      
      val changed = removeRelationsTo(annotation, UUID.fromString("a00566be-c51a-4831-a270-c700f06bc205"))
      changed.relations.size must equalTo(0)
    }
    
  }
  
} 
Example 119
Source File: VisitSpec.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.visit

import java.util.UUID
import services.ContentType
import services.RuntimeAccessLevel
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import org.joda.time.{ DateTime, DateTimeZone }
import org.joda.time.format.DateTimeFormat
import play.api.libs.json.Json
import play.api.test._
import play.api.test.Helpers._
import scala.io.Source

@RunWith(classOf[JUnitRunner])
class VisitSpec extends Specification {
  
  private val DATE_TIME_PATTERN = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ")
  private val visitedAt = DateTime.parse("2016-11-08T07:27:00Z", DATE_TIME_PATTERN).withZone(DateTimeZone.UTC)

  "The sample Visit" should {
    
    "be properly created from JSON" in {
      val json = Source.fromFile("test/resources/services/visit/visit.json").getLines().mkString("\n")
      val result = Json.fromJson[Visit](Json.parse(json))
            
      result.isSuccess must equalTo(true) 
      
      val visit = result.get
      visit.url must equalTo("http://recogito.pelagios.org/document/fb2f3hm1ihnwgn/part/1/edit")
      visit.referer must equalTo(Some("http://recogito.pelagios.org/rainer"))
      visit.visitedAt must equalTo(visitedAt)  
      visit.responseFormat must equalTo("text/html")
      visit.accessLevel must equalTo(Some(RuntimeAccessLevel.READ_ALL))
      
      val client = visit.client
      client.userAgent must equalTo("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36")
      client.browser must equalTo("CHROME")
      client.os must equalTo("LINUX")
      client.deviceType must equalTo("COMPUTER")
      
      val item = visit.visitedItem.get
      item.documentId must equalTo("fb2f3hm1ihnwgn")
      item.documentOwner must equalTo("rainer")
      item.filepartId must equalTo(Some(UUID.fromString("a7126845-16ac-434b-99bd-0f297e227822")))
      item.contentType must equalTo(Some(ContentType.TEXT_PLAIN))
    }
    
  }
  
  "JSON serialization/parsing roundtrip" should {
    
    "yield an equal Visit" in {
      val visit = Visit(
        "http://recogito.pelagios.org/document/fb2f3hm1ihnwgn/part/1/edit",
        Some("http://recogito.pelagios.org/rainer"),
        visitedAt,
        Client(
          "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
          "CHROME",
          "LINUX",
          "COMPUTER"
        ),
        "text/html",
        Some(VisitedItem(
          "fb2f3hm1ihnwgn",
          "rainer",
          Some(UUID.randomUUID),
          Some(ContentType.TEXT_PLAIN)
        )),
        Some(RuntimeAccessLevel.READ_ALL)
      )
        
      // Convert to JSON
      val serialized = Json.prettyPrint(Json.toJson(visit))
      
      val parseResult = Json.fromJson[Visit](Json.parse(serialized))
      parseResult.isSuccess must equalTo(true)
      parseResult.get must equalTo(visit)
    }
    
  }
  
} 
Example 120
Source File: PatchExamples.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.examples.patch

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import skuber._
import skuber.json.format._
import skuber.apps.v1beta1.StatefulSet

import scala.concurrent.Await
import scala.concurrent.duration.Duration.Inf
import play.api.libs.json.{Format, Json}
import skuber.api.patch.JsonMergePatch

object PatchExamples extends App {

  // API patch method.
  // This will change the replica count on the statefulset causing it to scale accordingly.
  case class ReplicaSpec(replicas: Int)
  case class ReplicaPatch(spec: ReplicaSpec) extends JsonMergePatch

  implicit val rsFmt: Format[ReplicaSpec] = Json.format[ReplicaSpec]
  implicit val rpFmt: Format[ReplicaPatch] = Json.format[ReplicaPatch]

  val statefulSetName = "nginx-patch-sts"

  def scaleNginx = {

    val nginxContainer = Container("nginx",image="nginx").exposePort(80)
    val nginxBaseSpec = Pod.Template.Spec().addContainer(nginxContainer)


    val nginxStsLabels=Map("patch-example" -> "statefulset")
    val nginxStsSel=LabelSelector(LabelSelector.IsEqualRequirement("patch-example","statefulset"))
    val nginxStsSpec=nginxBaseSpec.addLabels(nginxStsLabels)
    val nginxStatefulSet= StatefulSet(statefulSetName)
      .withReplicas(4)
      .withServiceName(statefulSetName)
      .withLabelSelector(nginxStsSel)
      .withTemplate(nginxStsSpec)

    // StatefulSet needs a headless service
    val nginxStsService: Service=Service(nginxStatefulSet.spec.get.serviceName.get, nginxStsLabels, 80).isHeadless

    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()
    implicit val dispatcher = system.dispatcher

    val k8s = k8sInit

    println("Creating nginx stateful set")
    val createdStsFut = for {
      svc <- k8s create nginxStsService
      sts <- k8s create nginxStatefulSet
    } yield sts
   
    val stsFut = createdStsFut recoverWith {
      case ex: K8SException if (ex.status.code.contains(409)) => {
        println("It seems the stateful set or service already exists - retrieving latest version")
        k8s get[StatefulSet] nginxStatefulSet.name
      }
    }

    // Wait for stateful set creation before proceeding
    val sts = Await.result(stsFut, Inf)
    println("waiting two minutes to allow Stateful Set creation to complete before patching it")
    Thread.sleep(120000)


    println("Patching stateful set to assign replica count of 1")

    // Create the Patch
    val singleReplicaPatch=ReplicaPatch(ReplicaSpec(1))
    val singleReplicaPatchJson=Json.toJson(singleReplicaPatch)
    val singleReplicaPatchJsonStr=singleReplicaPatchJson.toString

    // Send the Patch to the statefulset on Kubernetes
    val patchedStsFut = k8s.patch[ReplicaPatch, StatefulSet](statefulSetName, singleReplicaPatch)

    val patchedSts = Await.result(patchedStsFut, Inf)
    println(s"Patched statefulset now has a desired replica count of ${patchedSts.spec.get.replicas}")
    println("waiting 5 minutes to allow scaling to be observed before cleaning up")
    Thread.sleep(300000)
    println("will now delete StatefulSet and its service")
    val cleanupRequested= for {
      sts <- k8s.deleteWithOptions[StatefulSet](nginxStatefulSet.name, DeleteOptions(propagationPolicy = Some(DeletePropagation.Foreground)))
      done <- k8s.delete[Service](nginxStsService.name)
    } yield done


    Await.ready(cleanupRequested, Inf)
    println("Finishing up")
    k8s.close
    system.terminate()
  }
  scaleNginx
} 
Example 121
Source File: BytesToWatchEventSource.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.api.watch

import akka.stream.scaladsl.{JsonFraming, Source}
import akka.util.ByteString
import play.api.libs.json.{Format, JsError, JsSuccess, Json}
import skuber.ObjectResource
import skuber.api.client.{K8SException, Status, WatchEvent}

import scala.concurrent.ExecutionContext


private[api] object BytesToWatchEventSource {
  def apply[O <: ObjectResource](bytesSource: Source[ByteString, _], bufSize: Int)(implicit ec: ExecutionContext, format: Format[O]): Source[WatchEvent[O], _] = {
    import skuber.json.format.apiobj.watchEventFormat
    bytesSource.via(
      JsonFraming.objectScanner(bufSize)
    ).map { singleEventBytes =>
      Json.parse(singleEventBytes.utf8String).validate(watchEventFormat[O]) match {
        case JsSuccess(value, _) => value
        case JsError(e) => throw new K8SException(Status(message = Some("Error parsing watched object"), details = Some(e.toString)))
      }
    }
  }
} 
Example 122
Source File: package.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.json.batch

import play.api.libs.json.{Format, JsPath, Json}
import skuber.batch.{Job, JobList, JobTemplate, CronJob, CronJobList}


import play.api.libs.functional.syntax._
import skuber._
import skuber.json.format._ // reuse some core formatters

package object format {

  // Job formatters
  implicit val jobConditionFormat: Format[Job.Condition] = (
      (JsPath \ "type").formatMaybeEmptyString() and
      (JsPath \ "status").formatMaybeEmptyString() and
      (JsPath \ "lastProbeTime").formatNullable[Timestamp] and
      (JsPath \ "lastTransitionTime").formatNullable[Timestamp] and
      (JsPath \ "reason").formatNullable[String] and
      (JsPath \ "message").formatNullable[String]
    )(Job.Condition.apply _, unlift(Job.Condition.unapply))

  implicit val jobStatusFormat: Format[Job.Status] = (
      (JsPath \ "conditions").formatMaybeEmptyList[Job.Condition] and
      (JsPath \ "startTime").formatNullable[Timestamp] and
      (JsPath \ "completionTime").formatNullable[Timestamp] and
      (JsPath \ "active").formatNullable[Int] and
      (JsPath \ "succeeded").formatNullable[Int] and
      (JsPath \ "failed").formatNullable[Int]
    )(Job.Status.apply _, unlift(Job.Status.unapply))

  implicit val jobSpecFormat: Format[Job.Spec] = (
      (JsPath \ "parallelism").formatNullable[Int] and
      (JsPath \ "completions").formatNullable[Int] and
      (JsPath \ "activeDeadlineSeconds").formatNullable[Long] and
      (JsPath \ "selector").formatNullableLabelSelector and
      (JsPath \ "manualSelector").formatNullable[Boolean] and
      (JsPath \ "template").formatNullable[Pod.Template.Spec] and
      (JsPath \ "backoffLimit").formatNullable[Int] and
      (JsPath \ "ttlSecondsAfterFinished").formatNullable[Int]
    )(Job.Spec.apply _, unlift(Job.Spec.unapply))

  implicit val jobFormat: Format[Job] = (
      (JsPath \ "kind").formatMaybeEmptyString() and
      (JsPath \ "apiVersion").formatMaybeEmptyString() and
      (JsPath \ "metadata").format[ObjectMeta] and
      (JsPath \ "spec").formatNullable[Job.Spec] and
      (JsPath \ "status").formatNullable[Job.Status]
    )(Job.apply _, unlift(Job.unapply))

  implicit val jobTmplSpecFmt: Format[JobTemplate.Spec] = Json.format[JobTemplate.Spec]

  implicit val cronJobSpecFmt:Format[CronJob.Spec] = Json.format[CronJob.Spec]

  implicit val cronJobStatusFmt: Format[CronJob.Status] = (
      (JsPath \ "lastScheduleTime").formatNullable[Timestamp] and
      (JsPath \ "active").formatMaybeEmptyList[ObjectReference]
  )(CronJob.Status.apply _, unlift(CronJob.Status.unapply))

  implicit val cronJob: Format[CronJob] = (
      (JsPath \ "kind").formatMaybeEmptyString() and
      (JsPath \ "apiVersion").formatMaybeEmptyString() and
      (JsPath \ "metadata").format[ObjectMeta] and
      (JsPath \ "spec").formatNullable[CronJob.Spec] and
      (JsPath \ "status").formatNullable[CronJob.Status]
  )(CronJob.apply _, unlift(CronJob.unapply))

  implicit val jobListFmt: Format[JobList] = ListResourceFormat[Job]
  implicit val cronJobListFmt: Format[CronJobList] = ListResourceFormat[CronJob]

} 
Example 123
Source File: Scale.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber

import play.api.libs.functional.syntax._
import play.api.libs.json.{Format, JsPath, Json}
import skuber.json.format.{maybeEmptyFormatMethods,jsPath2LabelSelFormat,objectMetaFormat}


case class Scale(
    val kind: String = "Scale",
    val apiVersion: String,
    val metadata: ObjectMeta,
    spec: Scale.Spec = Scale.Spec(),
    status: Option[Scale.Status] = None) extends ObjectResource
{
  def withSpecReplicas(count: Int) =  this.copy(spec=Scale.Spec(Some(count)))
  def withStatusReplicas(count: Int) = {
    val newStatus = this.status.map(_.copy(replicas = count)).getOrElse(Scale.Status(replicas=count))
    this.copy(status=Some(newStatus))
  }
}
    
object Scale {

  def named(name: String, apiVersion: String=v1) = new Scale(apiVersion=apiVersion,metadata=ObjectMeta(name=name))

  case class Spec(replicas: Option[Int] = None)
  object Spec {
    implicit val scaleSpecFormat: Format[Scale.Spec] = Json.format[Scale.Spec]
  }

  case class Status(
    replicas: Int = 0,
    selector: Option[LabelSelector] = None,
    targetSelector: Option[String] = None
  )

  object Status {
    implicit val scaleStatusFormat: Format[Scale.Status] = (
      (JsPath \ "replicas").formatMaybeEmptyInt() and
      (JsPath \ "selector").formatNullableLabelSelector and
      (JsPath \ "targetSelector").formatNullable[String]
    )(Scale.Status.apply _, unlift(Scale.Status.unapply))
  }

  implicit val scaleFormat: Format[Scale] = Json.format[Scale]

  // Any object resource type [O <: ObjectResource] that supports a Scale subresource must provide an implicit value of
  // SubresourceSpec type to enable the client API method `scale` to be used on such resources
  // Kubernetes supports Scale subresources on ReplicationController/ReplicaSet/Deployment/StatefulSet types
  trait SubresourceSpec[O <: ObjectResource] {
    def apiVersion: String // the API version to be set on any Scale subresource of the specific resource type O
  }
} 
Example 124
Source File: HorizontalPodAutoscaler.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.autoscaling

import play.api.libs.functional.syntax.unlift
import play.api.libs.json.{Format,  Json}
import skuber.ResourceSpecification.{Names, Scope}
import skuber.{NonCoreResourceSpecification, ObjectMeta, ObjectResource, ReplicationController, ResourceDefinition, Timestamp}
import skuber.json.format.objectMetaFormat


case class HorizontalPodAutoscaler(
  	val kind: String ="HorizontalPodAutoscaler",
  	override val apiVersion: String =  "autoscaling/v1",
    val metadata: ObjectMeta,
    spec: HorizontalPodAutoscaler.Spec,
    status: Option[HorizontalPodAutoscaler.Status] = None) 
      extends ObjectResource {

  def withResourceVersion(version: String) = this.copy(metadata = metadata.copy(resourceVersion=version))

  def withMinReplicas(min: Int) = this.copy(spec=this.spec.copy(minReplicas=Some(min)))
  def withMaxReplicas(max: Int) = this.copy(spec=this.spec.copy(maxReplicas=max))
  def withCPUTargetUtilization(cpu: Int) =
    this.copy(spec=this.spec.copy(cpuUtilization=Some(CPUTargetUtilization(cpu))))
}
      
object HorizontalPodAutoscaler {

  val specification=NonCoreResourceSpecification(
    apiGroup = "autoscaling",
    version = "v1",
    scope = Scope.Namespaced,
    names = Names(
      plural = "horizontalpodautoscalers",
      singular = "horizontalpodautoscaler",
      kind = "HorizontalPodAutoscaler",
      shortNames = List("hpa")
    )
  )
  implicit val hpasDef = new ResourceDefinition[HorizontalPodAutoscaler] { def spec=specification }
  implicit val hpasListDef = new ResourceDefinition[HorizontalPodAutoscalerList] { def spec=specification }

  def scale(rc: ReplicationController): HorizontalPodAutoscaler = 
    build(rc.name, rc.metadata.namespace, "ReplicationController")

  def scale(de: skuber.apps.Deployment): HorizontalPodAutoscaler =
    build(de.name, de.metadata.namespace, "Deployment")
   
  def build(name: String, namespace: String, kind: String, apiVersion: String = "v1") : HorizontalPodAutoscaler = {
    val meta = ObjectMeta(name=name,namespace=namespace)
    val scaleTargetRef = CrossVersionObjectReference(
        kind=kind,
        name=name,
        apiVersion=apiVersion)
   HorizontalPodAutoscaler(metadata=meta,spec=Spec(scaleTargetRef=scaleTargetRef))
  }

  case class Spec(
    scaleTargetRef: CrossVersionObjectReference,
    minReplicas: Option[Int] = Some(1),
    maxReplicas: Int = 1,
    cpuUtilization: Option[CPUTargetUtilization] = None
  )
  case class CrossVersionObjectReference(
    apiVersion: String = "autoscaling/v1",
    kind: String = "CrossVersionObjectReference",
    name: String
  )
  case class Status(
    observedGeneration: Option[Long] = None,
    lastScaleTime: Option[Timestamp] = None,
    currentReplicas: Int = 0,
    desiredReplicas: Int = 0,
    currentCPUUtilizationPercentage: Option[Int] = None)

  // HorizontalPodAutoscaler Json formatters
  implicit val cpuTUFmt: Format[CPUTargetUtilization] = Json.format[CPUTargetUtilization]
  implicit val cvObjRefFmt: Format[CrossVersionObjectReference] = Json.format[CrossVersionObjectReference]
  implicit val hpasSpecFmt: Format[HorizontalPodAutoscaler.Spec] = Json.format[HorizontalPodAutoscaler.Spec]
  implicit val hpasStatusFmt: Format[HorizontalPodAutoscaler.Status] = Json.format[HorizontalPodAutoscaler.Status]
  implicit val hpasFmt: Format[HorizontalPodAutoscaler] =  Json.format[HorizontalPodAutoscaler]
} 
Example 125
Source File: PodDisruptionBudgetSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.policy.v1beta1

import org.specs2.mutable.Specification
import play.api.libs.json.{JsSuccess, Json}
import skuber.LabelSelector.dsl._

class PodDisruptionBudgetSpec extends Specification {
  import PodDisruptionBudget._
  "A PodDisruptionBudget can" >> {
    "decoded from json" >> {
      val pdb = PodDisruptionBudget("someName")
        .withMaxUnavailable(Left(2))
        .withMinAvailable(Left(1))
        .withLabelSelector("application" is "someApplicationName")

      Json.parse(createJson("/examplePodDisruptionBudget.json")).validate[PodDisruptionBudget] mustEqual JsSuccess(pdb)
    }
    "encode to json" >> {
      Json.toJson(
        PodDisruptionBudget("someName")
          .withMaxUnavailable(Left(2))
          .withMinAvailable(Left(1))
          .withLabelSelector("application" is "someApplicationName")
      ) mustEqual Json.parse(createJson("/examplePodDisruptionBudget.json"))
    }
  }

  private def createJson(file: String): String = {
    val source = scala.io.Source.fromURL(getClass.getResource(file))
    try source.mkString finally source.close()
  }
} 
Example 126
Source File: ScaleSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.apps

import org.specs2.mutable.Specification
import skuber.{Container, LabelSelector, ObjectMeta, Pod, ReplicationController, Scale}
import play.api.libs.json.Json


class ScaleSpec extends Specification {
  "This is a unit specification for the skuber Scale class. ".txt
  
  "A Scale object can be constructed from a name and replica count" >> {
    val scale=Scale.named("example").withSpecReplicas(10)
    scale.spec.replicas mustEqual Some(10)
    scale.name mustEqual "example"
    scale.status mustEqual None
  }
  
  "A scale object can be written to Json and then read back again successfully" >> {

      val scale= Scale(
        apiVersion="autoscaling/v1",
        metadata=ObjectMeta(name="example", namespace="na"),
        spec=Scale.Spec(replicas=Some(10))
      )
      
      val readScale = Json.fromJson[Scale](Json.toJson(scale)).get
      readScale mustEqual scale
  }
  
  "A scale object can be read directly from a JSON string" >> {
    val scaleJsonStr = """
{
  "kind": "Scale",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "redis-master",
    "namespace": "default",
    "selfLink": "/apis/extensions/v1beta1/namespaces/default/replicationcontrollers/redis-master/scale",
    "creationTimestamp": "2015-12-29T11:55:14Z"
  },
  "spec": {
    "replicas": 1
  },
  "status": {
    "replicas": 1,
    "targetSelector": "redis-master"
  }
}
"""
    val scale = Json.parse(scaleJsonStr).as[Scale]
    scale.kind mustEqual "Scale"
    scale.name mustEqual "redis-master"
    scale.spec.replicas mustEqual Some(1)
    scale.status mustEqual Some(Scale.Status(replicas=1, selector=None, targetSelector=Some("redis-master")))
  }

  "A scale object can contain NO replicas" >> {
    val scaleJsonObj =
      """
        |{
        |  "kind": "Scale",
        |  "apiVersion": "extensions/v1beta1",
        |  "metadata": {
        |    "name": "redis-master",
        |    "namespace": "default",
        |    "selfLink": "/apis/extensions/v1beta1/namespaces/default/replicationcontrollers/redis-master/scale",
        |    "creationTimestamp": "2015-12-29T11:55:14Z"
        |  },
        |  "spec": {
        |  },
        |  "status": {
        |    "replicas": 1,
        |    "targetSelector": "redis-master"
        |  }
        |}
      """.stripMargin
    val scale = Json.parse(scaleJsonObj).as[Scale]
    scale.kind mustEqual "Scale"
    scale.name mustEqual "redis-master"
    scale.spec.replicas mustEqual None
  }
} 
Example 127
Source File: PlayJsonSupport.scala    From kafka-serde-scala   with Apache License 2.0 5 votes vote down vote up
package io.github.azhur.kafkaserdeplayjson

import java.nio.charset.StandardCharsets.UTF_8
import java.util

import io.github.azhur.kafkaserdeplayjson.PlayJsonSupport.PlayJsonError
import org.apache.kafka.common.errors.SerializationException
import org.apache.kafka.common.serialization.{ Deserializer, Serde, Serializer }
import play.api.libs.json.{ JsError, JsValue, Json, Reads, Writes }

import scala.language.implicitConversions
import scala.util.control.NonFatal

trait PlayJsonSupport {
  implicit def toSerializer[T <: AnyRef](
      implicit writes: Writes[T],
      printer: JsValue => String = Json.stringify
  ): Serializer[T] =
    new Serializer[T] {
      override def configure(configs: util.Map[String, _], isKey: Boolean): Unit = {}
      override def close(): Unit                                                 = {}
      override def serialize(topic: String, data: T): Array[Byte] =
        if (data == null) null
        else
          try printer(writes.writes(data)).getBytes(UTF_8)
          catch {
            case NonFatal(e) => throw new SerializationException(e)
          }
    }

  implicit def toDeserializer[T >: Null <: AnyRef: Manifest](
      implicit reads: Reads[T]
  ): Deserializer[T] =
    new Deserializer[T] {
      override def configure(configs: util.Map[String, _], isKey: Boolean): Unit = {}
      override def close(): Unit                                                 = {}
      override def deserialize(topic: String, data: Array[Byte]): T =
        if (data == null) null
        else
          reads
            .reads(Json.parse(new String(data, UTF_8)))
            .recoverTotal { e =>
              throw new SerializationException(PlayJsonError(e))
            }
    }

  implicit def toSerde[T >: Null <: AnyRef: Manifest](
      implicit writes: Writes[T],
      reads: Reads[T],
      printer: JsValue => String = Json.stringify
  ): Serde[T] =
    new Serde[T] {
      override def configure(configs: util.Map[String, _], isKey: Boolean): Unit = {}
      override def close(): Unit                                                 = {}
      override def serializer(): Serializer[T]                                   = toSerializer[T]
      override def deserializer(): Deserializer[T]                               = toDeserializer[T]
    }
}

object PlayJsonSupport extends PlayJsonSupport {
  final case class PlayJsonError(error: JsError) extends RuntimeException {
    override def getMessage: String =
      JsError.toJson(error).toString()
  }
} 
Example 128
Source File: CommInfoRequest.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class CommInfoRequest(
  target_name: String
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(CommInfoRequest.commInfoRequestWrites).toString
}

object CommInfoRequest extends TypeString {
  implicit val commInfoRequestReads = Json.reads[CommInfoRequest]
  implicit val commInfoRequestWrites = Json.writes[CommInfoRequest]

  
  override def toTypeString: String = "comm_info_request"
} 
Example 129
Source File: ExecuteResult.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.{KernelMessageContent, Data, Metadata}
import play.api.libs.json.Json

case class ExecuteResult (
  execution_count: Int,
  data: Data,
  metadata: Metadata
)  extends KernelMessageContent {
  def hasContent = data != null && data.exists(x => x._2 != null && x._2.nonEmpty)
  override def content : String =
    Json.toJson(this)(ExecuteResult.executeResultWrites).toString
}

object ExecuteResult extends TypeString {
  implicit val executeResultReads = Json.reads[ExecuteResult]
  implicit val executeResultWrites = Json.writes[ExecuteResult]

  
  override def toTypeString: String = "execute_result"
} 
Example 130
Source File: ShutdownReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class ShutdownReply(
  restart: Boolean
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(ShutdownReply.shutdownReplyWrites).toString
}

object ShutdownReply extends TypeString {
  implicit val shutdownReplyReads = Json.reads[ShutdownReply]
  implicit val shutdownReplyWrites = Json.writes[ShutdownReply]

  
  override def toTypeString: String = "shutdown_reply"
} 
Example 131
Source File: ConnectReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class ConnectReply(
  shell_port: Int,
  iopub_port: Int,
  stdin_port: Int,
  hb_port: Int
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(ConnectReply.connectReplyWrites).toString
}

object ConnectReply extends TypeString {
  implicit val connectReplyReads = Json.reads[ConnectReply]
  implicit val connectReplyWrites = Json.writes[ConnectReply]

  
  override def toTypeString: String = "connect_reply"
} 
Example 132
Source File: CommInfoReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class CommInfoReply(
  comms: Map[String, Map[String, String]]
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(CommInfoReply.commInfoReplyWrites).toString
}

object CommInfoReply extends TypeString {
  implicit val commInfoReplyReads = Json.reads[CommInfoReply]
  implicit val commInfoReplyWrites = Json.writes[CommInfoReply]

  
  override def toTypeString: String = "comm_info_reply"
} 
Example 133
Source File: IsCompleteReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.{KernelMessageContent}
import play.api.libs.json.{Json, Reads, Writes}

case class IsCompleteReply (
                           status: String,
                           indent: String
                         ) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(IsCompleteReply.isCompleteReplyWrites).toString
}

object IsCompleteReply extends TypeString {
  implicit val isCompleteReplyReads: Reads[IsCompleteReply] = Json.reads[IsCompleteReply]
  implicit val isCompleteReplyWrites: Writes[IsCompleteReply] = Json.writes[IsCompleteReply]

  
  override def toTypeString: String = "complete_reply"
} 
Example 134
Source File: CommOpen.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5._
import play.api.libs.json.Json

case class CommOpen(comm_id: UUID, target_name: String, data: MsgData)
  extends KernelMessageContent with CommContent
{
  override def content : String =
    Json.toJson(this)(CommOpen.commOpenWrites).toString
}

object CommOpen extends TypeString {
  implicit val commOpenReads = Json.reads[CommOpen]
  implicit val commOpenWrites = Json.writes[CommOpen]

  
  override def toTypeString: String = "comm_open"
} 
Example 135
Source File: ShutdownRequest.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class ShutdownRequest(
  restart: Boolean
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(ShutdownRequest.shutdownRequestWrites).toString
}

object ShutdownRequest extends TypeString {
  implicit val shutdownRequestReads = Json.reads[ShutdownRequest]
  implicit val shutdownRequestWrites = Json.writes[ShutdownRequest]

  
  override def toTypeString: String = "shutdown_request"
} 
Example 136
Source File: ErrorContent.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

import scala.language.implicitConversions

case class ErrorContent(
  ename: String,
  evalue: String,
  traceback: List[String]
) extends KernelMessageContent{
  override def content : String =
    Json.toJson(this)(ErrorContent.errorContentWrites).toString
}

object ErrorContent extends TypeString {
  implicit val errorContentReads = Json.reads[ErrorContent]
  implicit val errorContentWrites = Json.writes[ErrorContent]

  implicit def ErrorContentToString(errorContent: ErrorContent): String ={
    Json.toJson(errorContent).toString
  }

  
  override def toTypeString: String = "error"
} 
Example 137
Source File: KernelInfoReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import org.apache.toree.kernel.protocol.v5.LanguageInfo
import play.api.libs.json.Json

case class KernelInfoReply (
  protocol_version: String,
  implementation: String,
  implementation_version: String,
  language_info: LanguageInfo,
  banner: String
) extends KernelMessageContent {
  override def content: String =
    Json.toJson(this)(KernelInfoReply.kernelInfoReplyWrites).toString
}

object KernelInfoReply extends TypeString {
  implicit val languageInfoReads = Json.reads[LanguageInfo]
  implicit val languageInfoWrites = Json.writes[LanguageInfo]
  implicit val kernelInfoReplyReads = Json.reads[KernelInfoReply]
  implicit val kernelInfoReplyWrites = Json.writes[KernelInfoReply]

  
  override def toTypeString: String = "kernel_info_reply"
} 
Example 138
Source File: CommMsg.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.{MsgData, KernelMessageContent, UUID}
import play.api.libs.json.Json

case class CommMsg(comm_id: UUID, data: MsgData)
  extends KernelMessageContent with CommContent
{
  override def content : String =
    Json.toJson(this)(CommMsg.commMsgWrites).toString
}

object CommMsg extends TypeString {
  implicit val commMsgReads = Json.reads[CommMsg]
  implicit val commMsgWrites = Json.writes[CommMsg]

  
  override def toTypeString: String = "comm_msg"
} 
Example 139
Source File: CompleteReply.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.{KernelMessageContent, Metadata}
import play.api.libs.json.Json

case class CompleteReply (
  matches: List[String],
  cursor_start: Int,
  cursor_end: Int,
  metadata: Metadata,
  status: String,
  ename: Option[String],
  evalue: Option[String],
  traceback: Option[List[String]]
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(CompleteReply.completeReplyWrites).toString
}

object CompleteReply extends TypeString {
  implicit val completeReplyReads = Json.reads[CompleteReply]
  implicit val completeReplyWrites = Json.writes[CompleteReply]

  
  override def toTypeString: String = "complete_reply"
} 
Example 140
Source File: HistoryRequest.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class HistoryRequest(
  output: Boolean,
  ras: Boolean,
  hist_access_type: String,
  session: Int,
  start: Int,
  stop: Int,
  n: Int,
  pattern: String,
  unique: Boolean
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(HistoryRequest.historyRequestWrites).toString
}

object HistoryRequest extends TypeString {
  implicit val historyRequestReads = Json.reads[HistoryRequest]
  implicit val historyRequestWrites = Json.writes[HistoryRequest]

  
  override def toTypeString: String = "history_request"
} 
Example 141
Source File: IsCompleteRequest.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.{Json, Reads, Writes}

case class IsCompleteRequest(
                            code: String
                          ) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(IsCompleteRequest.isCompleteRequestWrites).toString
}

object IsCompleteRequest extends TypeString {
  implicit val isCompleteRequestReads: Reads[IsCompleteRequest] = Json.reads[IsCompleteRequest]
  implicit val isCompleteRequestWrites: Writes[IsCompleteRequest] = Json.writes[IsCompleteRequest]

  
  override def toTypeString: String = "is_complete_request"
} 
Example 142
Source File: CompleteRequest.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.apache.toree.kernel.protocol.v5.KernelMessageContent
import play.api.libs.json.Json

case class CompleteRequest(
  code: String,
  cursor_pos: Int
) extends KernelMessageContent {
  override def content : String =
    Json.toJson(this)(CompleteRequest.completeRequestWrites).toString
}

object CompleteRequest extends TypeString {
  implicit val completeRequestReads = Json.reads[CompleteRequest]
  implicit val completeRequestWrites = Json.writes[CompleteRequest]

  
  override def toTypeString: String = "complete_request"
} 
Example 143
Source File: HeaderSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5

import org.scalatest.{Matchers, FunSpec}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, Json, JsValue}

class HeaderSpec extends FunSpec with Matchers {
  val headerJson: JsValue = Json.parse("""
  {
    "msg_id": "<UUID>",
    "username": "<STRING>",
    "session": "<UUID>",
    "msg_type": "<STRING>",
    "version": "<FLOAT>"
  }
  """)

  val header: Header = Header(
    "<UUID>", "<STRING>", "<UUID>", "<STRING>", "<FLOAT>"
  )

  describe("Header") {
    describe("when null") {
      it("should implicitly convert to empty json") {
        val header: Header = null
        Json.toJson(header).toString() should be ("{}")
      }
    }

    describe("implicit conversions") {
      it("should implicitly convert from valid json to a header instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        headerJson.as[Header] should be (header)
      }

      it("should also work with asOpt") {
        // This is safer, but we lose the error information as it returns
        // None if the conversion fails
        val newHeader = headerJson.asOpt[Header]

        newHeader.get should be (header)
      }

      it("should also work with validate") {
        // This is the safest as it collects all error information (not just first error) and reports it
        val headerResults = headerJson.validate[Header]

        headerResults.fold(
          (invalid: Seq[(JsPath, Seq[ValidationError])]) => println("Failed!"),
          (valid: Header) => valid
        ) should be (header)
      }

      it("should implicitly convert from a header instance to valid json") {
        Json.toJson(header) should be (headerJson)
      }
    }
  }
} 
Example 144
Source File: ConnectReplySpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.scalatest.{FunSpec, Matchers}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, JsValue, Json}

class ConnectReplySpec extends FunSpec with Matchers {


  val connectReplyJson: JsValue = Json.parse("""
  {
    "shell_port": 11111,
    "iopub_port": 22222,
    "stdin_port": 33333,
    "hb_port": 44444
  }
  """)

  val connectReply: ConnectReply = ConnectReply(11111,22222,33333,44444)

  describe("ConnectReply") {
    describe("#toTypeString") {
      it("should return correct type") {
        ConnectReply.toTypeString should be ("connect_reply")
      }
    }

    describe("implicit conversions") {
      it("should implicitly convert from valid json to a ConnectReply instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        connectReplyJson.as[ConnectReply] should be (connectReply)
      }

      it("should also work with asOpt") {
        // This is safer, but we lose the error information as it returns
        // None if the conversion fails
        val newConnectReply = connectReplyJson.asOpt[ConnectReply]

        newConnectReply.get should be (connectReply)
      }

      it("should also work with validate") {
        // This is the safest as it collects all error information (not just first error) and reports it
        val ConnectReplyResults = connectReplyJson.validate[ConnectReply]

        ConnectReplyResults.fold(
          (invalid: Seq[(JsPath, Seq[ValidationError])]) => println("Failed!"),
          (valid: ConnectReply) => valid
        ) should be (connectReply)
      }

      it("should implicitly convert from a ConnectReply instance to valid json") {
        Json.toJson(connectReply) should be (connectReplyJson)
      }
    }
  }

} 
Example 145
Source File: CompleteReplySpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.scalatest.{Matchers, FunSpec}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, JsValue, Json}

class CompleteReplySpec extends FunSpec with Matchers {


  val completeReplyJson: JsValue = Json.parse("""
  {
    "matches": [],
    "cursor_start": 1,
    "cursor_end": 5,
    "metadata": {},
    "status": "<STRING>"
  }
  """)

  val completeReply: CompleteReply = CompleteReply(
    List(), 1, 5, Map(), "<STRING>", None, None, None
  )

  describe("CompleteReply") {
    describe("#toTypeString") {
      it("should return correct type") {
        CompleteReply.toTypeString should be ("complete_reply")
      }
    }

    describe("implicit conversions") {
      it("should implicitly convert from valid json to a CompleteReply instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        completeReplyJson.as[CompleteReply] should be (completeReply)
      }

      it("should also work with asOpt") {
        // This is safer, but we lose the error information as it returns
        // None if the conversion fails
        val newCompleteReply = completeReplyJson.asOpt[CompleteReply]

        newCompleteReply.get should be (completeReply)
      }

      it("should also work with validate") {
        // This is the safest as it collects all error information (not just first error) and reports it
        val CompleteReplyResults = completeReplyJson.validate[CompleteReply]

        CompleteReplyResults.fold(
          (invalid: Seq[(JsPath, Seq[ValidationError])]) => println("Failed!"),
          (valid: CompleteReply) => valid
        ) should be (completeReply)
      }

      it("should implicitly convert from a CompleteReply instance to valid json") {
        Json.toJson(completeReply) should be (completeReplyJson)
      }
    }
  }

} 
Example 146
Source File: KernelStatusSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.content

import org.scalatest.{FunSpec, Matchers}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, JsValue, Json}

class KernelStatusSpec extends FunSpec with Matchers {
  val kernelStatusJson: JsValue = Json.parse("""
  {
    "execution_state": "<STRING>"
  }
  """)

  val kernelStatus: KernelStatus = KernelStatus("<STRING>")

  describe("KernelStatus") {
    describe("#toTypeString") {
      it("should return correct type") {
        KernelStatus.toTypeString should be ("status")
      }
    }

    describe("implicit conversions") {
      it("should implicitly convert from valid json to a kernelStatus instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        kernelStatusJson.as[KernelStatus] should be (kernelStatus)
      }

      it("should also work with asOpt") {
        // This is safer, but we lose the error information as it returns
        // None if the conversion fails
        val newKernelStatus = kernelStatusJson.asOpt[KernelStatus]

        newKernelStatus.get should be (kernelStatus)
      }

      it("should also work with validate") {
        // This is the safest as it collects all error information (not just first error) and reports it
        val kernelStatusResults = kernelStatusJson.validate[KernelStatus]

        kernelStatusResults.fold(
          (invalid: Seq[(JsPath, Seq[ValidationError])]) => println("Failed!"),
          (valid: KernelStatus) => valid
        ) should be (kernelStatus)
      }

      it("should implicitly convert from a kernelStatus instance to valid json") {
        Json.toJson(kernelStatus) should be (kernelStatusJson)
      }
    }
  }
} 
Example 147
Source File: package.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol

//import akka.zeromq.ZMQMessage
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content.{CompleteRequest, ExecuteRequest}
import play.api.libs.json.{JsValue, Json}

package object v5Test {
  //  The header for the message
  val MockHeader : Header = Header("<UUID>","<USER>","<SESSION>",
    MessageType.Outgoing.ClearOutput.toString, "<VERSION>")
  //  The parent header for the message
  val MockParenHeader: Header = Header("<PARENT-UUID>","<PARENT-USER>","<PARENT-SESSION>",
    MessageType.Outgoing.ClearOutput.toString, "<PARENT-VERSION>")
  //  The actual kernel message
  val MockKernelMessage : KernelMessage = KernelMessage(Seq("<ID>".getBytes), "<SIGNATURE>", MockHeader,
    MockParenHeader, Metadata(), "<CONTENT>")
  //  Use the implicit to convert the KernelMessage to ZMQMessage
  //val MockZMQMessage : ZMQMessage = MockKernelMessage

  val MockExecuteRequest: ExecuteRequest =
    ExecuteRequest("spark code", false, true, Map(), false)
  val MockExecuteRequestKernelMessage = MockKernelMessage.copy(
    contentString =  Json.toJson(MockExecuteRequest).toString
  )
  val MockKernelMessageWithBadExecuteRequest = new KernelMessage(
    Seq[Array[Byte]](), "test message", MockHeader, MockParenHeader, Metadata(),
    """
        {"code" : 124 }
    """
  )
  val MockCompleteRequest: CompleteRequest = CompleteRequest("", 0)
  val MockCompleteRequestKernelMessage: KernelMessage = MockKernelMessage.copy(contentString = Json.toJson(MockCompleteRequest).toString)
  val MockKernelMessageWithBadJSON: KernelMessage = MockKernelMessage.copy(contentString = "inval1d")
} 
Example 148
Source File: SignatureCheckerActorSpecForIntegration.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package integration.security

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.communication.security.{Hmac, SignatureCheckerActor}
import com.typesafe.config.ConfigFactory
import org.scalatest.{BeforeAndAfter, FunSpecLike, Matchers}
import play.api.libs.json.Json

object SignatureCheckerActorSpecForIntegration {
  val config = """
    akka {
      loglevel = "WARNING"
    }"""
}

class SignatureCheckerActorSpecForIntegration extends TestKit(
  ActorSystem(
    "SignatureCheckerActorSpec",
    ConfigFactory.parseString(SignatureCheckerActorSpecForIntegration.config)
  )
) with ImplicitSender with FunSpecLike with Matchers with BeforeAndAfter
{

  private val sigKey = "12345"
  private val signature =
    "1c4859a7606fd93eb5f73c3d9642f9bc860453ba42063961a00d02ed820147b5"
  private val goodMessage =
    KernelMessage(
      null, signature,
      Header("a", "b", "c", "d", "e"),
      ParentHeader("f", "g", "h", "i", "j"),
      Metadata(),
      "<STRING>"
    )
  private val badMessage =
    KernelMessage(
      null, "wrong signature",
      Header("a", "b", "c", "d", "e"),
      ParentHeader("f", "g", "h", "i", "j"),
      Metadata(),
      "<STRING>"
    )

  private var signatureChecker: ActorRef = _

  before {
    val hmac = Hmac(sigKey)
    signatureChecker =
      system.actorOf(Props(classOf[SignatureCheckerActor], hmac))
  }

  after {
    signatureChecker = null
  }

  describe("SignatureCheckerActor") {
    describe("#receive") {
      it("should return true if the kernel message is valid") {
        val blob =
          Json.stringify(Json.toJson(goodMessage.header)) ::
          Json.stringify(Json.toJson(goodMessage.parentHeader)) ::
          Json.stringify(Json.toJson(goodMessage.metadata)) ::
          goodMessage.contentString ::
          Nil
        signatureChecker ! ((goodMessage.signature, blob))
        expectMsg(true)
      }

      it("should return false if the kernel message is invalid") {
        val blob =
          Json.stringify(Json.toJson(badMessage.header)) ::
          Json.stringify(Json.toJson(badMessage.parentHeader)) ::
          Json.stringify(Json.toJson(badMessage.metadata)) ::
          badMessage.contentString ::
          Nil
        signatureChecker ! ((badMessage.signature, blob))
        expectMsg(false)
      }
    }
  }
} 
Example 149
Source File: StdinClient.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.client.socket

import akka.actor.Actor
import org.apache.toree.communication.ZMQMessage
import org.apache.toree.communication.security.SecurityActorType
import org.apache.toree.kernel.protocol.v5.client.ActorLoader
import org.apache.toree.kernel.protocol.v5.{HeaderBuilder, KMBuilder, KernelMessage}
import org.apache.toree.kernel.protocol.v5.content.{InputReply, InputRequest}
import org.apache.toree.utils.LogLike
import org.apache.toree.kernel.protocol.v5.client.Utilities._
import play.api.libs.json.Json

import StdinClient._
import akka.pattern.ask

import scala.concurrent.duration._
import scala.concurrent.Await

object StdinClient {
  case class ResponseFunctionMessage(responseFunction: ResponseFunction)
  type ResponseFunction = (String, Boolean) => String
  val EmptyResponseFunction: ResponseFunction = (_, _) => ""
}


  private var responseFunc: ResponseFunction = EmptyResponseFunction

  override def receive: Receive = {
    case responseFunctionMessage: ResponseFunctionMessage =>
      logger.debug("Updating response function")
      this.responseFunc = responseFunctionMessage.responseFunction

    case message: ZMQMessage =>
      logger.debug("Received stdin kernel message")
      val kernelMessage: KernelMessage = message
      val messageType = kernelMessage.header.msg_type

      if (messageType == InputRequest.toTypeString) {
        logger.debug("Message is an input request")

        val inputRequest =
          Json.parse(kernelMessage.contentString).as[InputRequest]
        val value = responseFunc(inputRequest.prompt, inputRequest.password)
        val inputReply = InputReply(value)

        val newKernelMessage = KMBuilder()
          .withParent(kernelMessage)
          .withHeader(HeaderBuilder.empty.copy(
            msg_type = InputReply.toTypeString,
            session = getSessionId
          ))
          .withContentString(inputReply)
          .build

        import scala.concurrent.ExecutionContext.Implicits.global
        val messageWithSignature = if (signatureEnabled) {
          val signatureManager =
            actorLoader.load(SecurityActorType.SignatureManager)
          val signatureMessage = signatureManager ? newKernelMessage
          Await.result(signatureMessage, 100.milliseconds)
            .asInstanceOf[KernelMessage]
        } else newKernelMessage

        val zmqMessage: ZMQMessage = messageWithSignature

        socket ! zmqMessage
      } else {
        logger.debug(s"Unknown message of type $messageType")
      }
  }
} 
Example 150
Source File: SocketConfig.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.client.socket

import com.typesafe.config.Config
import play.api.libs.json.Json

case class SocketConfig (
  stdin_port: Int,
  control_port: Int,
  hb_port: Int,
  shell_port: Int,
  iopub_port: Int,
  ip : String,
  transport: String,
  signature_scheme: String,
  key: String
)

object SocketConfig {
  implicit val socketConfigReads = Json.reads[SocketConfig]
  implicit val socketConfigWrites = Json.writes[SocketConfig]

  def fromConfig(config: Config) = {
    new SocketConfig(
      config.getInt("stdin_port"),
      config.getInt("control_port"),
      config.getInt("hb_port"),
      config.getInt("shell_port"),
      config.getInt("iopub_port"),
      config.getString("ip"),
      config.getString("transport"),
      config.getString("signature_scheme"),
      config.getString("key")
    )
  }
} 
Example 151
Source File: Utilities.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.client

import java.nio.charset.Charset

import akka.util.{ByteString, Timeout}
import org.apache.toree.communication.ZMQMessage
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content.ExecuteRequest
import org.apache.toree.utils.LogLike
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, Json, Reads}

import scala.concurrent.duration._

object Utilities extends LogLike {
  //
  // NOTE: This is brought in to remove feature warnings regarding the use of
  //       implicit conversions regarding the following:
  //
  //       1. ByteStringToString
  //       2. ZMQMessageToKernelMessage
  //
  import scala.language.implicitConversions

  private val sessionId: UUID = java.util.UUID.randomUUID().toString

  
  implicit val timeout = Timeout(21474835.seconds) // Maximum delay

  implicit def ByteStringToString(byteString : ByteString) : String = {
    new String(byteString.toArray, Charset.forName("UTF-8"))
  }

  implicit def StringToByteString(string : String) : ByteString = {
    ByteString(string.getBytes)
  }

  implicit def ZMQMessageToKernelMessage(message: ZMQMessage): KernelMessage = {
    val delimiterIndex: Int =
      message.frames.indexOf(ByteString("<IDS|MSG>".getBytes))
    //  TODO Handle the case where there is no delimiter
    val ids: Seq[Array[Byte]] =
      message.frames.take(delimiterIndex).map(
        (byteString : ByteString) =>  { byteString.toArray }
      )
    val header = Json.parse(message.frames(delimiterIndex + 2)).as[Header]
    val parentHeader = Json.parse(message.frames(delimiterIndex + 3)).validate[ParentHeader].fold[ParentHeader](
      // TODO: Investigate better solution than setting parentHeader to null for {}
      (invalid: Seq[(JsPath, Seq[ValidationError])]) => null, //HeaderBuilder.empty,
      (valid: ParentHeader) => valid
    )
    val metadata = Json.parse(message.frames(delimiterIndex + 4)).as[Metadata]

    KMBuilder().withIds(ids.toList)
               .withSignature(message.frame(delimiterIndex + 1))
               .withHeader(header)
               .withParentHeader(parentHeader)
               .withMetadata(metadata)
               .withContentString(message.frame(delimiterIndex + 5)).build(false)
  }

  implicit def KernelMessageToZMQMessage(kernelMessage : KernelMessage) : ZMQMessage = {
    val frames: scala.collection.mutable.ListBuffer[ByteString] = scala.collection.mutable.ListBuffer()
    kernelMessage.ids.map((id : Array[Byte]) => frames += ByteString.apply(id) )
    frames += "<IDS|MSG>"
    frames += kernelMessage.signature
    frames += Json.toJson(kernelMessage.header).toString()
    frames += Json.toJson(kernelMessage.parentHeader).toString()
    frames += Json.toJson(kernelMessage.metadata).toString
    frames += kernelMessage.contentString
    ZMQMessage(frames  : _*)
  }

  def parseAndHandle[T](json: String, reads: Reads[T], handler: T => Unit) : Unit = {
    Json.parse(json).validate[T](reads).fold(
      (invalid: Seq[(JsPath, Seq[ValidationError])]) =>
        logger.error(s"Could not parse JSON, ${json}"),
      (content: T) => handler(content)
    )
  }

  def getSessionId = sessionId

  def toKernelMessage(message: ExecuteRequest): KernelMessage = {
    // construct a kernel message whose content is an ExecuteRequest
    val id = java.util.UUID.randomUUID().toString
    val header = Header(
      id, "spark", sessionId, MessageType.Incoming.ExecuteRequest.toString, "5.0")

    KMBuilder().withIds(Seq[Array[Byte]]()).withSignature("").withHeader(header)
      .withParentHeader(HeaderBuilder.empty).withContentString(message).build
  }

} 
Example 152
Source File: ShellClientSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.client.socket

import java.util.UUID

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestProbe, ImplicitSender, TestKit}
import org.apache.toree.communication.ZMQMessage
import org.apache.toree.communication.security.SecurityActorType
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.client.ActorLoader
import org.apache.toree.kernel.protocol.v5.content.ExecuteRequest
import org.scalatest.mock.MockitoSugar
import org.scalatest.{Matchers, FunSpecLike}
import org.mockito.Mockito._
import org.mockito.Matchers._
import play.api.libs.json.Json

class ShellClientSpec extends TestKit(ActorSystem("ShellActorSpec"))
  with ImplicitSender with FunSpecLike with Matchers with MockitoSugar {
  private val SignatureEnabled = true

  describe("ShellClientActor") {
    val socketFactory = mock[SocketFactory]
    val mockActorLoader = mock[ActorLoader]
    val probe : TestProbe = TestProbe()
    when(socketFactory.ShellClient(
      any(classOf[ActorSystem]), any(classOf[ActorRef])
    )).thenReturn(probe.ref)

    val signatureManagerProbe = TestProbe()
    doReturn(system.actorSelection(signatureManagerProbe.ref.path.toString))
      .when(mockActorLoader).load(SecurityActorType.SignatureManager)

    val shellClient = system.actorOf(Props(
      classOf[ShellClient], socketFactory, mockActorLoader, SignatureEnabled
    ))

    describe("send execute request") {
      it("should send execute request") {
        val request = ExecuteRequest(
          "foo", false, true, UserExpressions(), true
        )
        val header = Header(
          UUID.randomUUID().toString, "spark",
          UUID.randomUUID().toString, MessageType.Incoming.ExecuteRequest.toString,
          "5.0"
        )
        val kernelMessage = KernelMessage(
          Seq[Array[Byte]](), "",
          header, HeaderBuilder.empty,
          Metadata(), Json.toJson(request).toString
        )
        shellClient ! kernelMessage

        // Echo back the kernel message sent to have a signature injected
        signatureManagerProbe.expectMsgClass(classOf[KernelMessage])
        signatureManagerProbe.reply(kernelMessage)

        probe.expectMsgClass(classOf[ZMQMessage])
      }
    }
  }
} 
Example 153
Source File: DataFrameConverter.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.utils

import org.apache.spark.sql.{Dataset, Row}
import org.apache.toree.plugins.Plugin
import play.api.libs.json.{JsObject, Json}

import scala.util.Try
import org.apache.toree.plugins.annotations.Init

import DataFrameConverter._

class DataFrameConverter extends Plugin with LogLike {
  @Init def init() = {
    register(this)
  }

  def convert(df: Dataset[Row], outputType: String, limit: Int = 10): Try[String] = {
    Try(
      outputType.toLowerCase() match {
        case "html" =>
          convertToHtml(df = df, limit = limit)
        case "json" =>
          convertToJson(df = df, limit = limit)
        case "csv" =>
          convertToCsv(df = df, limit = limit)
      }
    )
  }

  private def convertToHtml(df: Dataset[Row], limit: Int = 10): String = {
      val columnFields = df.schema.fieldNames.map(columnName => {
        s"<th>${columnName}</th>"
      }).reduce(_ + _)
      val columns = s"<tr>${columnFields}</tr>"
      val rows = df.rdd.map(row => {
        val fieldValues = row.toSeq.map(field => {
         s"<td>${fieldToString(field)}</td>"
        }).reduce(_ + _)
        s"<tr>${fieldValues}</tr>"
      }).take(limit).reduce(_ + _)
      s"<table>${columns}${rows}</table>"
  }

  private def convertToJson(df: Dataset[Row], limit: Int = 10): String = {
    val schema = Json.toJson(df.schema.fieldNames)
    val transformed = df.rdd.map(row =>
      row.toSeq.map(fieldToString).toArray)
    val rows = transformed.take(limit)
    JsObject(Seq(
      "columns" -> schema,
      "rows" -> Json.toJson(rows)
    )).toString()
  }

  private def convertToCsv(df: Dataset[Row], limit: Int = 10): String = {
      val headers = df.schema.fieldNames.reduce(_ + "," + _)
      val rows = df.rdd.map(row => {
        row.toSeq.map(fieldToString).reduce(_ + "," + _)
      }).take(limit).reduce(_ + "\n" + _)
      s"${headers}\n${rows}"
  }

}

object DataFrameConverter {

  def fieldToString(any: Any): String =
    any match {
      case null => "null"
      case seq: Seq[_] => seq.mkString("[", ", ", "]")
      case _ => any.toString
    }

} 
Example 154
Source File: CodeCompleteHandler.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.handler

import akka.pattern.ask
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content._
import org.apache.toree.kernel.protocol.v5.kernel.{ActorLoader, Utilities}
import Utilities._
import org.apache.toree.utils.{MessageLogSupport, LogLike}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, Json}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Success

class CodeCompleteHandler(actorLoader: ActorLoader)
  extends BaseHandler(actorLoader) with MessageLogSupport
{
  override def process(kernelMessage: KernelMessage): Future[_] = {
    logKernelMessageAction("Generating code completion for", kernelMessage)
    Utilities.parseAndHandle(
      kernelMessage.contentString,
      CompleteRequest.completeRequestReads,
      completeRequest(kernelMessage, _ : CompleteRequest)
    )
  }

  private def completeRequest(km: KernelMessage, cr: CompleteRequest):
                              Future[(Int, List[String])] = {
    val interpreterActor = actorLoader.load(SystemActorType.Interpreter)
    val codeCompleteFuture = ask(interpreterActor, cr).mapTo[(Int, List[String])]
    codeCompleteFuture.onComplete {
      case Success(tuple) =>
        val reply = CompleteReplyOk(tuple._2, tuple._1,
                                    cr.cursor_pos, Metadata())
        val completeReplyType = MessageType.Outgoing.CompleteReply.toString
        logKernelMessageAction("Sending code complete reply for", km)
        actorLoader.load(SystemActorType.KernelMessageRelay) !
          km.copy(
            header = HeaderBuilder.create(completeReplyType),
            parentHeader = km.header,
            contentString = Json.toJson(reply).toString
          )
      case _ =>
        new Exception("Parse error in CodeCompleteHandler")
    }
    codeCompleteFuture
  }
} 
Example 155
Source File: IsCompleteHandler.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.handler

import akka.pattern.ask
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content._
import org.apache.toree.kernel.protocol.v5.kernel.{ActorLoader, Utilities}
import Utilities._
import org.apache.toree.utils.{MessageLogSupport, LogLike}
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, Json}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.Success

class IsCompleteHandler(actorLoader: ActorLoader)
  extends BaseHandler(actorLoader) with MessageLogSupport
{
  override def process(kernelMessage: KernelMessage): Future[_] = {
    logKernelMessageAction("Determining if code is complete for", kernelMessage)
    Utilities.parseAndHandle(
      kernelMessage.contentString,
      IsCompleteRequest.isCompleteRequestReads,
      isCompleteRequest(kernelMessage, _ : IsCompleteRequest)
    )
  }

  private def isCompleteRequest(km: KernelMessage, cr: IsCompleteRequest):
  Future[(String, String)] = {
    val interpreterActor = actorLoader.load(SystemActorType.Interpreter)
    val codeCompleteFuture = ask(interpreterActor, cr).mapTo[(String, String)]
    codeCompleteFuture.onComplete {
      case Success(tuple) =>
        val reply = IsCompleteReply(tuple._1, tuple._2)
        val isCompleteReplyType = MessageType.Outgoing.IsCompleteReply.toString
        logKernelMessageAction("Sending is complete reply for", km)
        actorLoader.load(SystemActorType.KernelMessageRelay) !
          km.copy(
            header = HeaderBuilder.create(isCompleteReplyType),
            parentHeader = km.header,
            contentString = Json.toJson(reply).toString
          )
      case _ =>
        new Exception("Parse error in CodeCompleteHandler")
    }
    codeCompleteFuture
  }
} 
Example 156
Source File: CommInfoRequestHandler.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.handler

import org.apache.toree.comm.CommStorage
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content.CommInfoReply
import org.apache.toree.kernel.protocol.v5.kernel.ActorLoader
import org.apache.toree.utils.MessageLogSupport
import play.api.libs.json.Json

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, future}


class CommInfoRequestHandler(
                              actorLoader: ActorLoader,
                              commStorage: CommStorage)
  extends BaseHandler(actorLoader) with MessageLogSupport
{

  def buildCommMap(targetName: String) = {
    commStorage.getCommIdsFromTarget(targetName) match {
      case Some(commVector) => {
        commVector.map(x => Map(x -> Map("target_name" -> targetName))).flatten.toMap
      }
      case _ => {
        Map()
      }
    }
  }

  override def process(kernelMessage: KernelMessage): Future[_] = Future {
    logKernelMessageAction("Initiating CommInfo request for", kernelMessage)

    val commMap = (Json.parse(kernelMessage.contentString) \ "target_name").asOpt[String] match {
      case Some(targetName) => {
        buildCommMap(targetName)
      }
      case None => {
        //target_name is missing from the kernel message so return all comms over every target
        commStorage.getTargets().map(buildCommMap(_)).reduce(_ ++ _)
      }
    }
    val commInfoReply = CommInfoReply(commMap.asInstanceOf[Map[String, Map[String, String]]])

    val kernelInfo = SparkKernelInfo

    val replyHeader = Header(
      java.util.UUID.randomUUID.toString,
      "",
      java.util.UUID.randomUUID.toString,
      CommInfoReply.toTypeString,
      kernelInfo.protocolVersion)

    val kernelResponseMessage = KMBuilder()
      .withIds(kernelMessage.ids)
      .withSignature("")
      .withHeader(replyHeader)
      .withParent(kernelMessage)
      .withContentString(commInfoReply).build

    actorLoader.load(SystemActorType.KernelMessageRelay) ! kernelResponseMessage
  }

} 
Example 157
Source File: InputRequestReplyHandler.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.handler

import akka.actor.ActorRef
import org.apache.toree.comm.{CommRegistrar, CommStorage}
import org.apache.toree.communication.utils.OrderedSupport
import org.apache.toree.kernel.protocol.v5.{SystemActorType, KernelMessage}
import org.apache.toree.kernel.protocol.v5.content.{InputReply, CommOpen}
import org.apache.toree.kernel.protocol.v5.kernel.{Utilities, ActorLoader}
import org.apache.toree.kernel.protocol.v5
import org.apache.toree.utils.MessageLogSupport
import play.api.libs.json.Json

import scala.concurrent.{Promise, Future}


class InputRequestReplyHandler(
  actorLoader: ActorLoader,
  responseMap: collection.mutable.Map[String, ActorRef]
) extends OrderedSupport with MessageLogSupport
{
  // TODO: Is there a better way than storing actor refs?
  def receive = {
    case kernelMessage: KernelMessage =>
      startProcessing()

      val kernelMessageType = kernelMessage.header.msg_type
      val inputRequestType = v5.MessageType.Outgoing.InputRequest.toString
      val inputReplyType = v5.MessageType.Incoming.InputReply.toString

      // Is this an outgoing message to request data?
      if (kernelMessageType == inputRequestType) {
        val session = kernelMessage.parentHeader.session
        responseMap(session) = sender

        logger.debug("Associating input request with session " + session)

        actorLoader.load(SystemActorType.KernelMessageRelay) ! kernelMessage

      // Is this an incoming response to a previous request for data?
      } else if (kernelMessageType == inputReplyType) {
        val session = kernelMessage.header.session
        val inputReply = Json.parse(kernelMessage.contentString).as[InputReply]

        logger.debug(s"Received input reply for session $session with value " +
          s"'${inputReply.value}'")

        responseMap(session) ! inputReply.value
        responseMap.remove(session)
      }

      finishedProcessing()
  }

  override def orderedTypes() : Seq[Class[_]] = {Seq(classOf[KernelMessage])}
} 
Example 158
Source File: SocketConfig.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.kernel.socket

import com.typesafe.config.Config
import play.api.libs.json.Json

case class SocketConfig (
  stdin_port: Int,
  control_port: Int,
  hb_port: Int,
  shell_port: Int,
  iopub_port: Int,
  ip : String,
  transport: String,
  signature_scheme: String,
  key: String
)

object SocketConfig {
  implicit val socketConfigReads = Json.reads[SocketConfig]
  implicit val socketConfigWrites = Json.writes[SocketConfig]

  def fromConfig(config: Config) = {
    new SocketConfig(
      config.getInt("stdin_port"),
      config.getInt("control_port"),
      config.getInt("hb_port"),
      config.getInt("shell_port"),
      config.getInt("iopub_port"),
      config.getString("ip"),
      config.getString("transport"),
      config.getString("signature_scheme"),
      config.getString("key")
    )
  }
} 
Example 159
Source File: Utilities.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.kernel

import java.nio.charset.Charset

import akka.util.{ByteString, Timeout}
import org.apache.toree.communication.ZMQMessage
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.utils.LogLike
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, Json, Reads}

import scala.concurrent.duration._

object Utilities extends LogLike {
  //
  // NOTE: This is brought in to remove feature warnings regarding the use of
  //       implicit conversions regarding the following:
  //
  //       1. ByteStringToString
  //       2. ZMQMessageToKernelMessage
  //
  import scala.language.implicitConversions

  
  implicit val timeout = Timeout(21474835.seconds)

  implicit def ByteStringToString(byteString : ByteString) : String = {
    new String(byteString.toArray, Charset.forName("UTF-8"))
  }

  implicit def StringToByteString(string : String) : ByteString = {
    ByteString(string.getBytes)
  }

  implicit def ZMQMessageToKernelMessage(message: ZMQMessage): KernelMessage = {
    val delimiterIndex: Int =
      message.frames.indexOf(ByteString("<IDS|MSG>".getBytes))
    //  TODO Handle the case where there is no delimiter
    val ids: Seq[Array[Byte]] =
      message.frames.take(delimiterIndex).map(
        (byteString : ByteString) =>  { byteString.toArray }
      )
    val header = Json.parse(message.frames(delimiterIndex + 2)).as[Header]
    // TODO: Investigate better solution than setting parentHeader to null for {}
    val parentHeader = parseAndHandle(message.frames(delimiterIndex + 3),
                                  ParentHeader.headerReads,
                                  handler = (valid: ParentHeader) => valid,
                                  errHandler = _ => null
    )
    val metadata = Json.parse(message.frames(delimiterIndex + 4)).as[Metadata]

    KMBuilder().withIds(ids.toList)
               .withSignature(message.frame(delimiterIndex + 1))
               .withHeader(header)
               .withParentHeader(parentHeader)
               .withMetadata(metadata)
               .withContentString(message.frame(delimiterIndex + 5)).build(false)
  }

  implicit def KernelMessageToZMQMessage(kernelMessage : KernelMessage) : ZMQMessage = {
    val frames: scala.collection.mutable.ListBuffer[ByteString] = scala.collection.mutable.ListBuffer()
    kernelMessage.ids.map((id : Array[Byte]) => frames += ByteString.apply(id) )
    frames += "<IDS|MSG>"
    frames += kernelMessage.signature
    frames += Json.toJson(kernelMessage.header).toString()
    frames += Json.toJson(kernelMessage.parentHeader).toString()
    frames += Json.toJson(kernelMessage.metadata).toString
    frames += kernelMessage.contentString
    ZMQMessage(frames  : _*)
  }

  def parseAndHandle[T, U](json: String, reads: Reads[T],
                           handler: T => U) : U = {
    parseAndHandle(json, reads, handler,
      (invalid: Seq[(JsPath, Seq[ValidationError])]) => {
        logger.error(s"Could not parse JSON, ${json}")
        throw new Throwable(s"Could not parse JSON, ${json}")
      }
    )
  }

  def parseAndHandle[T, U](json: String, reads: Reads[T],
                           handler: T => U,
                           errHandler: Seq[(JsPath, Seq[ValidationError])] => U) : U = {
    Json.parse(json).validate[T](reads).fold(
      errHandler,
      (content: T) => handler(content)
    )
  }
} 
Example 160
Source File: StatusDispatch.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.dispatch

import akka.actor.Actor
import org.apache.toree.kernel.protocol.v5.KernelStatusType.KernelStatusType
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content.KernelStatus
import org.apache.toree.kernel.protocol.v5.kernel.ActorLoader
import org.apache.toree.utils.LogLike
import play.api.libs.json.Json

class StatusDispatch(actorLoader: ActorLoader) extends Actor with LogLike {
  private def sendStatusMessage(kernelStatus: KernelStatusType, parentHeader: Header) {
    //  Create the status message and send it to the relay
    val km : KernelMessage = KMBuilder()
      .withIds(Seq(MessageType.Outgoing.Status.toString.getBytes))
      .withSignature("")
      .withHeader(MessageType.Outgoing.Status)
      .withParentHeader(parentHeader)
      .withContentString(KernelStatus(kernelStatus.toString)).build

    actorLoader.load(SystemActorType.KernelMessageRelay) ! km
  }

  override def receive: Receive = {
    case (status: KernelStatusType, null) =>
      //  TODO Determine if this should be null or an empty parent header
      sendStatusMessage(status, null)

    case (status: KernelStatusType, parentHeader: Header) =>
      sendStatusMessage( status, parentHeader )

    case status: KernelStatusType =>
      sendStatusMessage(status , HeaderBuilder.empty)
  }
} 
Example 161
Source File: DataFrameConverterSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.utils

import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.{DataFrame, Row}
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.scalatest.{BeforeAndAfterAll, FunSpec, Matchers}
import play.api.libs.json.{JsArray, JsString, Json}
import test.utils.SparkContextProvider

import scala.collection.mutable

class DataFrameConverterSpec extends FunSpec with MockitoSugar with Matchers with BeforeAndAfterAll {

  lazy val spark = SparkContextProvider.sparkContext

  override protected def afterAll(): Unit = {
    spark.stop()
    super.afterAll()
  }

  val dataFrameConverter: DataFrameConverter = new DataFrameConverter
  val mockDataFrame = mock[DataFrame]
  val mockRdd = spark.parallelize(Seq(Row(new mutable.WrappedArray.ofRef(Array("test1", "test2")), 2, null)))
  val mockStruct = mock[StructType]
  val columns = Seq("foo", "bar").toArray

  doReturn(mockStruct).when(mockDataFrame).schema
  doReturn(columns).when(mockStruct).fieldNames
  doReturn(mockRdd).when(mockDataFrame).rdd

  describe("DataFrameConverter") {
    describe("#convert") {
      it("should convert to a valid JSON object") {
        val someJson = dataFrameConverter.convert(mockDataFrame, "json")
        val jsValue = Json.parse(someJson.get)
        jsValue \ "columns" should be (JsArray(Seq(JsString("foo"), JsString("bar"))))
        jsValue \ "rows" should be (JsArray(Seq(
          JsArray(Seq(JsString("[test1, test2]"), JsString("2"), JsString("null")))
        )))
      }
      it("should convert to csv") {
        val csv = dataFrameConverter.convert(mockDataFrame, "csv").get
        val values = csv.split("\n")
        values(0) shouldBe "foo,bar"
        values(1) shouldBe "[test1, test2],2,null"
      }
      it("should convert to html") {
        val html = dataFrameConverter.convert(mockDataFrame, "html").get
        html.contains("<th>foo</th>") should be(true)
        html.contains("<th>bar</th>") should be(true)
        html.contains("<td>[test1, test2]</td>") should be(true)
        html.contains("<td>2</td>") should be(true)
        html.contains("<td>null</td>") should be(true)
      }
      it("should convert limit the selection") {
        val someLimited = dataFrameConverter.convert(mockDataFrame, "csv", 1)
        val limitedLines = someLimited.get.split("\n")
        limitedLines.length should be(2)
      }
      it("should return a Failure for invalid types") {
        val result = dataFrameConverter.convert(mockDataFrame, "Invalid Type")
        result.isFailure should be(true)
      }
    }
  }
} 
Example 162
Source File: KernelInfoRequestHandlerSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.handler
import akka.actor.{ActorSelection, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit, TestProbe}
import org.apache.toree.Main
import org.apache.toree.kernel.protocol.v5.content.KernelInfoReply
import org.apache.toree.kernel.protocol.v5.kernel.ActorLoader
import org.apache.toree.kernel.protocol.v5._
import org.mockito.AdditionalMatchers.{not => mockNot}
import org.mockito.Matchers.{eq => mockEq}
import com.typesafe.config.ConfigFactory
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.scalatest.{FunSpecLike, Matchers}
import play.api.libs.json.Json
import test.utils.MaxAkkaTestTimeout

object KernelInfoRequestHandlerSpec {
  val config = """
    akka {
      loglevel = "WARNING"
    }"""
}

class KernelInfoRequestHandlerSpec extends TestKit(
  ActorSystem("KernelInfoRequestHandlerSpec",
    ConfigFactory.parseString(KernelInfoRequestHandlerSpec.config),
    Main.getClass.getClassLoader)
) with ImplicitSender with FunSpecLike with Matchers with MockitoSugar {
  val actorLoader: ActorLoader =  mock[ActorLoader]
  val actor = system.actorOf(Props(classOf[KernelInfoRequestHandler], actorLoader, LanguageInfo("test", "1.0.0", Some(".test"))))

  val relayProbe : TestProbe = TestProbe()
  val relaySelection : ActorSelection =
    system.actorSelection(relayProbe.ref.path)
  when(actorLoader.load(SystemActorType.KernelMessageRelay))
    .thenReturn(relaySelection)
  when(actorLoader.load(mockNot(mockEq(SystemActorType.KernelMessageRelay))))
    .thenReturn(system.actorSelection(""))

  val header = Header("","","","","")
  val kernelMessage = new KernelMessage(
    Seq[Array[Byte]](), "test message", header, header, Metadata(), "{}"
  )

  describe("Kernel Info Request Handler") {
    it("should return a KernelMessage containing kernel info response") {
      actor ! kernelMessage
      val reply = relayProbe.receiveOne(MaxAkkaTestTimeout).asInstanceOf[KernelMessage]
      val kernelInfo = Json.parse(reply.contentString).as[KernelInfoReply]
      kernelInfo.implementation should be ("spark")
    }
  }
} 
Example 163
Source File: SocketConfigSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.kernel.socket

import com.typesafe.config.ConfigFactory
import org.scalatest.{FunSpec, Matchers}
import org.slf4j.LoggerFactory
import play.api.data.validation.ValidationError
import play.api.libs.json.{JsPath, JsValue, Json}

class SocketConfigSpec extends FunSpec with Matchers {
  val logger = LoggerFactory.getLogger("jt4")
  //logger.error("WOOT!")

  private val jsonString: String =
    """
    {
      "stdin_port": 10000,
      "control_port": 10001,
      "hb_port": 10002,
      "shell_port": 10003,
      "iopub_port": 10004,
      "ip": "1.2.3.4",
      "transport": "tcp",
      "signature_scheme": "hmac-sha256",
      "key": ""
    }
    """.stripMargin

  val socketConfigJson: JsValue = Json.parse(jsonString)

  val socketConfigFromConfig = SocketConfig.fromConfig(ConfigFactory.parseString(jsonString))

  val socketConfig = SocketConfig(
    10000, 10001, 10002, 10003, 10004, "1.2.3.4", "tcp", "hmac-sha256", ""
  )

  describe("SocketConfig") {
    describe("implicit conversions") {
      it("should implicitly convert from valid json to a SocketConfig instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        socketConfigJson.as[SocketConfig] should be (socketConfig)
      }

      it("should also work with asOpt") {
        // This is safer, but we lose the error information as it returns
        // None if the conversion fails
        val newCompleteRequest = socketConfigJson.asOpt[SocketConfig]

        newCompleteRequest.get should be (socketConfig)
      }

      it("should also work with validate") {
        // This is the safest as it collects all error information (not just first error) and reports it
        val CompleteRequestResults = socketConfigJson.validate[SocketConfig]

        CompleteRequestResults.fold(
          (invalid: Seq[(JsPath, Seq[ValidationError])]) => println("Failed!"),
          (valid: SocketConfig) => valid
        ) should be (socketConfig)
      }

      it("should implicitly convert from a SocketConfig instance to valid json") {
        Json.toJson(socketConfig) should be (socketConfigJson)
      }
    }
    describe("#toConfig") {
      it("should implicitly convert from valid json to a SocketConfig instance") {
        // This is the least safe way to convert as an error is thrown if it fails
        socketConfigFromConfig should be (socketConfig)
      }
      
      it("should convert json file to SocketConfig object") {
        socketConfigFromConfig.stdin_port should be (10000)
      }
    }
  }
} 
Example 164
Source File: StatusDispatchSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.protocol.v5.dispatch

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
import org.apache.toree.kernel.protocol.v5._
import org.apache.toree.kernel.protocol.v5.content.KernelStatus
import org.apache.toree.kernel.protocol.v5.kernel.ActorLoader
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.scalatest.{BeforeAndAfter, FunSpecLike, Matchers}
import play.api.libs.json.Json
import test.utils.MaxAkkaTestTimeout

class StatusDispatchSpec extends TestKit(
  ActorSystem(
    "StatusDispatchSystem",
    None,
    Some(org.apache.toree.Main.getClass.getClassLoader)
  )
)
with FunSpecLike with Matchers with MockitoSugar with BeforeAndAfter{
  var statusDispatchRef: ActorRef = _
  var relayProbe: TestProbe = _
  before {
    //  Mock the relay with a probe
    relayProbe = TestProbe()
    //  Mock the ActorLoader
    val mockActorLoader: ActorLoader = mock[ActorLoader]
    when(mockActorLoader.load(SystemActorType.KernelMessageRelay))
      .thenReturn(system.actorSelection(relayProbe.ref.path.toString))

    statusDispatchRef = system.actorOf(Props(classOf[StatusDispatch],mockActorLoader))
  }


  describe("StatusDispatch") {
    describe("#receive( KernelStatusType )") {
      it("should send a status message to the relay") {
        statusDispatchRef ! KernelStatusType.Busy
        //  Check the kernel message is the correct type
        val statusMessage: KernelMessage = relayProbe.receiveOne(MaxAkkaTestTimeout).asInstanceOf[KernelMessage]
        statusMessage.header.msg_type should be (MessageType.Outgoing.Status.toString)
        //  Check the status is what we sent
        val status: KernelStatus = Json.parse(statusMessage.contentString).as[KernelStatus]
         status.execution_state should be (KernelStatusType.Busy.toString)
      }
    }

    describe("#receive( KernelStatusType, Header )") {
      it("should send a status message to the relay") {
        val tuple = Tuple2(KernelStatusType.Busy, mock[Header])
        statusDispatchRef ! tuple
        //  Check the kernel message is the correct type
        val statusMessage: KernelMessage = relayProbe.receiveOne(MaxAkkaTestTimeout).asInstanceOf[KernelMessage]
        statusMessage.header.msg_type should be (MessageType.Outgoing.Status.toString)
        //  Check the status is what we sent
        val status: KernelStatus = Json.parse(statusMessage.contentString).as[KernelStatus]
        status.execution_state should be (KernelStatusType.Busy.toString)
      }
    }
  }
} 
Example 165
Source File: StreamMethodsSpec.scala    From incubator-toree   with Apache License 2.0 5 votes vote down vote up
package org.apache.toree.kernel.api

import akka.actor.ActorSystem
import akka.testkit.{ImplicitSender, TestKit, TestProbe}
import org.apache.toree.kernel.protocol.v5
import org.apache.toree.kernel.protocol.v5.KernelMessage
import org.scalatest.mock.MockitoSugar
import org.scalatest.{FunSpecLike, BeforeAndAfter, Matchers}
import play.api.libs.json.Json
import test.utils.MaxAkkaTestTimeout
import org.mockito.Mockito._

class StreamMethodsSpec extends TestKit(
  ActorSystem(
    "StreamMethodsSpec",
    None,
    Some(org.apache.toree.Main.getClass.getClassLoader)
  )
) with ImplicitSender with FunSpecLike with Matchers with MockitoSugar
  with BeforeAndAfter
{

  private var kernelMessageRelayProbe: TestProbe = _
  private var mockParentHeader: v5.ParentHeader = _
  private var mockActorLoader: v5.kernel.ActorLoader = _
  private var mockKernelMessage: v5.KernelMessage = _
  private var streamMethods: StreamMethods = _

  before {
    kernelMessageRelayProbe = TestProbe()

    mockParentHeader = mock[v5.ParentHeader]

    mockActorLoader = mock[v5.kernel.ActorLoader]
    doReturn(system.actorSelection(kernelMessageRelayProbe.ref.path))
      .when(mockActorLoader).load(v5.SystemActorType.KernelMessageRelay)

    mockKernelMessage = mock[v5.KernelMessage]
    doReturn(mockParentHeader).when(mockKernelMessage).header

    streamMethods = new StreamMethods(mockActorLoader, mockKernelMessage)
  }

  describe("StreamMethods") {
    describe("#()") {
      it("should put the header of the given message as the parent header") {
        val expected = mockKernelMessage.header
        val actual = streamMethods.kmBuilder.build.parentHeader

        actual should be (expected)
      }
    }

    describe("#sendAll") {
      it("should send a message containing all of the given text") {
        val expected = "some text"

        streamMethods.sendAll(expected)

        val outgoingMessage = kernelMessageRelayProbe.receiveOne(MaxAkkaTestTimeout)
        val kernelMessage = outgoingMessage.asInstanceOf[KernelMessage]

        val actual = Json.parse(kernelMessage.contentString)
          .as[v5.content.StreamContent].text

        actual should be (expected)
      }
    }
  }

} 
Example 166
Source File: SwaggerSpecRunner.scala    From play-swagger   with Apache License 2.0 5 votes vote down vote up
package com.iheart.playSwagger

import java.nio.file.{ Files, Paths, StandardOpenOption }

import play.api.libs.json.{ JsValue, Json }

import scala.util.{ Failure, Success, Try }

object SwaggerSpecRunner extends App {
  implicit def cl: ClassLoader = getClass.getClassLoader

  val targetFile :: routesFile :: domainNameSpaceArgs :: outputTransformersArgs :: swaggerV3String :: apiVersion :: swaggerPrettyJson :: namingStrategy :: Nil = args.toList
  private def fileArg = Paths.get(targetFile)
  private def swaggerJson = {
    val swaggerV3 = java.lang.Boolean.parseBoolean(swaggerV3String)
    val domainModelQualifier = PrefixDomainModelQualifier(domainNameSpaceArgs.split(","): _*)
    val transformersStrs: Seq[String] = if (outputTransformersArgs.isEmpty) Seq() else outputTransformersArgs.split(",")
    val transformers = transformersStrs.map { clazz ⇒
      Try(cl.loadClass(clazz).asSubclass(classOf[OutputTransformer]).newInstance()) match {
        case Failure(ex: ClassCastException) ⇒
          throw new IllegalArgumentException("Transformer should be a subclass of com.iheart.playSwagger.OutputTransformer:" + clazz, ex)
        case Failure(ex) ⇒ throw new IllegalArgumentException("Could not create transformer", ex)
        case Success(el) ⇒ el
      }
    }

    val swaggerSpec: JsValue = SwaggerSpecGenerator(
      NamingStrategy.from(namingStrategy),
      domainModelQualifier,
      outputTransformers = transformers,
      swaggerV3 = swaggerV3,
      apiVersion = Some(apiVersion)).generate(routesFile).get

    if (swaggerPrettyJson.toBoolean) Json.prettyPrint(swaggerSpec)
    else swaggerSpec.toString
  }

  Files.write(fileArg, swaggerJson.getBytes, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
} 
Example 167
Source File: LeaseStatusTestSuite.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.it.sync.transactions

import com.typesafe.config.{Config, ConfigFactory}
import com.wavesplatform.api.http.TransactionsApiRoute.LeaseStatus
import com.wavesplatform.it.api.SyncHttpApi._
import com.wavesplatform.it.sync._
import com.wavesplatform.it.transactions.BaseTransactionSuite
import org.scalatest.CancelAfterFailure
import play.api.libs.json.Json

class LeaseStatusTestSuite extends BaseTransactionSuite with CancelAfterFailure {
  import LeaseStatusTestSuite._

  override protected def nodeConfigs: Seq[Config] = Configs

  test("verification of leasing status") {
    val createdLeaseTxId = sender.lease(firstAddress, secondAddress, leasingAmount, leasingFee = minFee).id
    nodes.waitForHeightAriseAndTxPresent(createdLeaseTxId)
    val status = getStatus(createdLeaseTxId)
    status shouldBe LeaseStatus.Active

    val cancelLeaseTxId = sender.cancelLease(firstAddress, createdLeaseTxId, fee = minFee).id
    miner.waitForTransaction(cancelLeaseTxId)
    nodes.waitForHeightArise()
    val status1 = getStatus(createdLeaseTxId)
    status1 shouldBe LeaseStatus.Canceled
    val sizeActiveLeases = sender.activeLeases(firstAddress).size
    sizeActiveLeases shouldBe 0
  }

  private def getStatus(txId: String): String = {
    val r = sender.get(s"/transactions/info/$txId")
    (Json.parse(r.getResponseBody) \ "status").as[String]

  }
}

object LeaseStatusTestSuite {
  private val blockGenerationOffset = "10000ms"
  import com.wavesplatform.it.NodeConfigs.Default

  private val minerConfig = ConfigFactory.parseString(s"""waves {
       |   miner{
       |      enable = yes
       |      minimal-block-generation-offset = $blockGenerationOffset
       |      quorum = 0
       |      micro-block-interval = 3s
       |      max-transactions-in-key-block = 0
       |   }
       |}
     """.stripMargin)

  private val notMinerConfig = ConfigFactory.parseString(s"""waves {
       |   miner.enable = no
       |   miner.minimal-block-generation-offset = $blockGenerationOffset
       |}
     """.stripMargin)

  val Configs: Seq[Config] = Seq(
    minerConfig.withFallback(Default.head),
    notMinerConfig.withFallback(Default(1))
  )

} 
Example 168
Source File: SmartTransactionsConstraintsSuite.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.it.async

import com.typesafe.config.Config
import com.wavesplatform.account.KeyPair
import com.wavesplatform.api.http.requests.SignedSetScriptRequest
import com.wavesplatform.common.utils.EitherExt2
import com.wavesplatform.it.api.AsyncHttpApi._
import com.wavesplatform.it.transactions.NodesFromDocker
import com.wavesplatform.it.{NodeConfigs, TransferSending}
import com.wavesplatform.lang.directives.values.V1
import com.wavesplatform.lang.script.v1.ExprScript
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.mining.MiningConstraints.MaxScriptRunsInBlock
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.smart.SetScriptTransaction
import org.scalatest._
import play.api.libs.json.{JsNumber, Json}

import scala.concurrent.Await.result
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

class SmartTransactionsConstraintsSuite extends FreeSpec with Matchers with TransferSending with NodesFromDocker {

  override protected val nodeConfigs: Seq[Config] = NodeConfigs.newBuilder
    .overrideBase(
      _.raw(
        s"""akka.http.server {
         |  parsing.max-content-length = 3737439
         |  request-timeout = 60s
         |}
         |
         |waves {
         |  miner.quorum = 0
         |
         |  blockchain.custom {
         |    functionality {
         |      pre-activated-features {
         |        2: 0
         |        4: 0
         |        11: 100500
         |      }
         |    }
         |  }
         |}""".stripMargin
      )
    )
    .withDefault(1)
    .build(false)

  private def miner                   = nodes.head
  private val smartPrivateKey  = KeyPair.fromSeed(NodeConfigs.Default(1).getString("account-seed")).explicitGet()
  private val simplePrivateKey = KeyPair.fromSeed(NodeConfigs.Default(2).getString("account-seed")).explicitGet()

  s"Block is limited by size after activation" in result(
    for {
      _ <- miner.signedBroadcast(Json.toJsObject(toRequest(setScriptTx(smartPrivateKey))) + ("type" -> JsNumber(13)))
      _ <- processRequests(generateTransfersFromAccount(MaxScriptRunsInBlock * 3, smartPrivateKey.toAddress.toString))
      _ <- miner.waitForHeight(5)
      _ <- processRequests(generateTransfersFromAccount(MaxScriptRunsInBlock * 3, smartPrivateKey.toAddress.toString))
      _ <- scala.concurrent.Future.sequence((0 to 9).map(_ =>
        processRequests(generateTransfersFromAccount((50 - MaxScriptRunsInBlock / 10), simplePrivateKey.toAddress.toString))))
      _                  <- miner.waitForHeight(6)
      blockWithSetScript <- miner.blockHeadersAt(2)
      restBlocks         <- miner.blockHeadersSeq(3, 4)
      newBlock           <- miner.blockHeadersAt(5)
    } yield {
      blockWithSetScript.transactionCount should (be <= (MaxScriptRunsInBlock + 1) and be >= 1)
      restBlocks.foreach { x =>
        x.transactionCount should be(MaxScriptRunsInBlock)
      }
      newBlock.transactionCount should be > MaxScriptRunsInBlock
    },
    12.minutes
  )

  private def setScriptTx(sender: KeyPair) =
    SetScriptTransaction
      .selfSigned(1.toByte, sender = sender, script = Some(ExprScript(V1, Terms.TRUE, checkSize = false).explicitGet()), fee = 1000000, timestamp = System.currentTimeMillis() - 5.minutes.toMillis)
      .explicitGet()

  private def toRequest(tx: SetScriptTransaction): SignedSetScriptRequest = SignedSetScriptRequest(
    version = Some(TxVersion.V1),
    senderPublicKey = tx.sender.toString,
    script = tx.script.map(_.bytes().base64),
    fee = tx.fee,
    timestamp = tx.timestamp,
    proofs = tx.proofs
  )

} 
Example 169
Source File: SetAssetScriptTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization.{ByteBufferOps, Deser}
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.assets.SetAssetScriptTransaction
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object SetAssetScriptTxSerializer {
  def toJson(tx: SetAssetScriptTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "assetId" -> asset.id.toString,
      "script"  -> script.map(_.bytes().base64)
    ) ++ (if (tx.version == TxVersion.V1) Json.obj("chainId" -> tx.chainId) else Json.obj())
  }

  def bodyBytes(tx: SetAssetScriptTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        Bytes.concat(
          Array(builder.typeId, version, chainId),
          sender.arr,
          asset.id.arr,
          Longs.toByteArray(fee),
          Longs.toByteArray(timestamp),
          Deser.serializeOptionOfArrayWithLength(script)(s => s.bytes().arr)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: SetAssetScriptTransaction): Array[Byte] =
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())

  def parseBytes(bytes: Array[Byte]): Try[SetAssetScriptTransaction] = Try {
    require(bytes.length > 2, "buffer underflow while parsing transaction")

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == 0 && buf.getByte == SetAssetScriptTransaction.typeId && buf.getByte == TxVersion.V1, "transaction type mismatch")
    require(buf.getByte == AddressScheme.current.chainId, "transaction chainId mismatch")

    val sender    = buf.getPublicKey
    val asset     = buf.getIssuedAsset
    val fee       = buf.getLong
    val timestamp = buf.getLong
    val script    = buf.getScript
    val proofs    = buf.getProofs
    SetAssetScriptTransaction(TxVersion.V1, sender, asset, script, fee, timestamp, proofs, AddressScheme.current.chainId)
  }
} 
Example 170
Source File: DataTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets.UTF_8

import com.google.common.primitives.{Bytes, Longs, Shorts}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization._
import com.wavesplatform.state.DataEntry.Type
import com.wavesplatform.state.{BinaryDataEntry, BooleanDataEntry, DataEntry, IntegerDataEntry, StringDataEntry}
import com.wavesplatform.transaction.{DataTransaction, TxVersion}
import com.wavesplatform.utils.StringBytes
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object DataTxSerializer {
  def toJson(tx: DataTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj("data" -> Json.toJson(data)
    )
  }

  def bodyBytes(tx: DataTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        Bytes.concat(
          Array(builder.typeId, version),
          sender.arr,
          Shorts.toByteArray(data.size.toShort),
          Bytes.concat(data.map(serializeEntry): _*),
          Longs.toByteArray(timestamp),
          Longs.toByteArray(fee)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  private def serializeEntry(e: DataEntry[_]): Array[Byte] = {
    val keyBytes = e.key.utf8Bytes
    val valueBytes = e match {
      case IntegerDataEntry(_, value) => Bytes.concat(Array(Type.Integer.id.toByte), Longs.toByteArray(value))
      case BooleanDataEntry(_, value) => Array(Type.Boolean.id, if (value) 1 else 0).map(_.toByte)
      case BinaryDataEntry(_, value)  => Bytes.concat(Array(Type.Binary.id.toByte), Deser.serializeArrayWithLength(value.arr))
      case StringDataEntry(_, value)  => Bytes.concat(Array(Type.String.id.toByte), Deser.serializeArrayWithLength(value.utf8Bytes))
      case other                      => throw new IllegalArgumentException(s"Unsupported data entry: $other")
    }
    Bytes.concat(Shorts.toByteArray(keyBytes.length.toShort), keyBytes, valueBytes)
  }

  def toBytes(tx: DataTransaction): Array[Byte] =
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())

  def parseBytes(bytes: Array[Byte]): Try[DataTransaction] = Try {
    def parseDataEntries(buf: ByteBuffer): Seq[DataEntry[_]] = {
      val entryCount = buf.getShort
      require(entryCount >= 0 && buf.remaining() > entryCount, s"Broken array size ($entryCount entries while ${buf.remaining()} bytes available)")
      Vector.fill(entryCount)(parseEntry(buf))
    }

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == 0 && buf.getByte == DataTransaction.typeId && buf.getByte == 1, "transaction type mismatch")

    val sender    = buf.getPublicKey
    val data      = parseDataEntries(buf)
    val timestamp = buf.getLong // Timestamp before fee
    val fee       = buf.getLong
    DataTransaction(TxVersion.V1, sender, data, fee, timestamp, buf.getProofs, AddressScheme.current.chainId)
  }

  private def parseEntry(buf: ByteBuffer): DataEntry[_] = {
    val key = new String(Deser.parseArrayWithLength(buf), UTF_8)
    buf.get match {
      case t if t == Type.Integer.id => IntegerDataEntry(key, buf.getLong)
      case t if t == Type.Boolean.id => BooleanDataEntry(key, buf.get != 0)
      case t if t == Type.Binary.id  => BinaryDataEntry(key, ByteStr(Deser.parseArrayWithLength(buf)))
      case t if t == Type.String.id  => StringDataEntry(key, new String(Deser.parseArrayWithLength(buf), UTF_8))
      case other           => throw new IllegalArgumentException(s"Unknown type $other")
    }
  }
} 
Example 171
Source File: ReissueTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.assets.ReissueTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object ReissueTxSerializer {
  def toJson(tx: ReissueTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "assetId"    -> asset.id.toString,
      "quantity"   -> quantity,
      "reissuable" -> reissuable
    ) ++ (if (tx.version == TxVersion.V2) Json.obj("chainId" -> chainId) else Json.obj())
  }

  def bodyBytes(tx: ReissueTransaction): Array[Byte] = {
    import tx._
    lazy val baseBytes = Bytes.concat(
      sender.arr,
      asset.id.arr,
      Longs.toByteArray(quantity),
      if (reissuable) Array(1: Byte) else Array(0: Byte),
      Longs.toByteArray(fee),
      Longs.toByteArray(timestamp)
    )

    version match {
      case TxVersion.V1 =>
        Bytes.concat(Array(typeId), baseBytes)

      case TxVersion.V2 =>
        Bytes.concat(
          Array(builder.typeId, version, chainId),
          baseBytes
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: ReissueTransaction): Array[Byte] = {
    tx.version match {
      case TxVersion.V1 => Bytes.concat(Array(tx.typeId), tx.proofs.toSignature.arr, this.bodyBytes(tx)) // Signature before body, typeId appears twice
      case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
      case _            => PBTransactionSerializer.bytes(tx)
    }
  }

  def parseBytes(bytes: Array[Byte]): Try[ReissueTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): ReissueTransaction = {
      val sender     = buf.getPublicKey
      val asset      = buf.getIssuedAsset
      val quantity   = buf.getLong
      val reissuable = buf.getBoolean
      val fee        = buf.getLong
      val timestamp  = buf.getLong
      ReissueTransaction(version, sender, asset, quantity, reissuable, fee, timestamp, Nil, AddressScheme.current.chainId)
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == ReissueTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 4, bytes.length - 4)
      parseCommonPart(TxVersion.V2, buf).copy(proofs = buf.getProofs)
    } else {
      require(bytes(0) == ReissueTransaction.typeId, "transaction type mismatch")
      val buf       = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      val signature = buf.getSignature
      require(buf.getByte == ReissueTransaction.typeId, "transaction type mismatch")
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(signature))
    }
  }
} 
Example 172
Source File: LeaseTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.serialization.ByteBufferOps
import com.wavesplatform.transaction.Asset.Waves
import com.wavesplatform.transaction.lease.LeaseTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object LeaseTxSerializer {
  def toJson(tx: LeaseTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "amount"    -> amount,
      "recipient" -> recipient.stringRepr
    )
  }

  def bodyBytes(tx: LeaseTransaction): Array[Byte] = {
    import tx._
    val baseBytes = Bytes.concat(sender.arr, recipient.bytes, Longs.toByteArray(amount), Longs.toByteArray(fee), Longs.toByteArray(timestamp))

    version match {
      case TxVersion.V1 => Bytes.concat(Array(typeId), baseBytes)
      case TxVersion.V2 => Bytes.concat(Array(typeId, version), Waves.byteRepr, baseBytes)
      case _            => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: LeaseTransaction): Array[Byte] = tx.version match {
    case TxVersion.V1 => Bytes.concat(this.bodyBytes(tx), tx.proofs.toSignature.arr)
    case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
    case _            => PBTransactionSerializer.bytes(tx)
  }

  def parseBytes(bytes: Array[Byte]): Try[LeaseTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): LeaseTransaction = {
      val sender    = buf.getPublicKey
      val recipient = buf.getAddressOrAlias
      val amount    = buf.getLong
      val fee       = buf.getLong
      val timestamp = buf.getLong
      LeaseTransaction(version, sender, recipient, amount, fee, timestamp, Nil, recipient.chainId)
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == LeaseTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 3, bytes.length - 3)
      require(buf.getAsset == Waves, "Leasing assets is not supported yet")
      parseCommonPart(TxVersion.V2, buf).copy(proofs = buf.getProofs)
    } else {
      require(bytes(0) == LeaseTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(buf.getSignature))
    }
  }
} 
Example 173
Source File: InvokeScriptTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils._
import com.wavesplatform.lang.v1.Serde
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.lang.v1.compiler.Terms.{EXPR, FUNCTION_CALL}
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves}
import com.wavesplatform.transaction.smart.InvokeScriptTransaction
import com.wavesplatform.transaction.smart.InvokeScriptTransaction.Payment
import com.wavesplatform.transaction.{Asset, TxVersion}
import play.api.libs.json.{JsArray, JsObject, JsString, Json}

import scala.util.Try

object InvokeScriptTxSerializer {
  def functionCallToJson(fc: Terms.FUNCTION_CALL): JsObject = {
    Json.obj(
      "function" -> JsString(fc.function.asInstanceOf[com.wavesplatform.lang.v1.FunctionHeader.User].internalName),
      "args" -> JsArray(
        fc.args.map {
          case Terms.ARR(elements) => Json.obj("type" -> "list", "value" -> elements.map(mapSingleArg))
          case other               => mapSingleArg(other)
        }
      )
    )
  }

  private def mapSingleArg(arg: EXPR) =
    arg match {
      case Terms.CONST_LONG(num)      => Json.obj("type" -> "integer", "value" -> num)
      case Terms.CONST_BOOLEAN(bool)  => Json.obj("type" -> "boolean", "value" -> bool)
      case Terms.CONST_BYTESTR(bytes) => Json.obj("type" -> "binary", "value" -> bytes.base64)
      case Terms.CONST_STRING(str)    => Json.obj("type" -> "string", "value" -> str)
      case arg                        => throw new NotImplementedError(s"Not supported: $arg")
    }

  def toJson(tx: InvokeScriptTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "dApp"    -> dAppAddressOrAlias.stringRepr,
      "payment" -> payments
    ) ++ (funcCallOpt match {
      case Some(fc) => Json.obj("call" -> this.functionCallToJson(fc))
      case None     => JsObject.empty
    })
  }

  def bodyBytes(tx: InvokeScriptTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        Bytes.concat(
          Array(builder.typeId, version, chainId),
          sender.arr,
          dAppAddressOrAlias.bytes,
          Deser.serializeOption(funcCallOpt)(Serde.serialize(_)),
          Deser.serializeArrays(payments.map(pmt => Longs.toByteArray(pmt.amount) ++ pmt.assetId.byteRepr)),
          Longs.toByteArray(fee),
          feeAssetId.byteRepr,
          Longs.toByteArray(timestamp)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: InvokeScriptTransaction): Array[Byte] =
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())

  def parseBytes(bytes: Array[Byte]): Try[InvokeScriptTransaction] = Try {
    def parsePayment(arr: Array[Byte]): Payment = {
      val amt               = Longs.fromByteArray(arr.take(8))
      val (maybeAssetId, _) = Deser.parseOption(arr, 8, 32)(ByteStr.apply)
      val asset             = maybeAssetId.fold[Asset](Waves)(IssuedAsset)
      Payment(amt, asset)
    }

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == 0 && buf.getByte == InvokeScriptTransaction.typeId && buf.getByte == 1, "transaction type mismatch")
    val chainId = buf.getByte
    require(chainId == AddressScheme.current.chainId, "chainId mismatch")

    val sender       = buf.getPublicKey
    val dApp         = buf.getAddressOrAlias
    val functionCall = Deser.parseOption(buf)(Serde.deserialize(_).explicitGet().asInstanceOf[FUNCTION_CALL])
    val payments     = Deser.parseArrays(buf).map(parsePayment)
    val fee          = buf.getLong
    val feeAssetId   = buf.getAsset
    val timestamp    = buf.getLong
    InvokeScriptTransaction(TxVersion.V1, sender, dApp, functionCall, payments, fee, feeAssetId, timestamp, buf.getProofs, chainId)
  }
} 
Example 174
Source File: SponsorFeeTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization.ByteBufferOps
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.assets.SponsorFeeTransaction
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object SponsorFeeTxSerializer {
  def toJson(tx: SponsorFeeTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "assetId"              -> asset.id.toString,
      "minSponsoredAssetFee" -> minSponsoredAssetFee
    )
  }

  def bodyBytes(tx: SponsorFeeTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        Bytes.concat(
          Array(builder.typeId, version),
          sender.arr,
          asset.id.arr,
          Longs.toByteArray(minSponsoredAssetFee.getOrElse(0)),
          Longs.toByteArray(fee),
          Longs.toByteArray(timestamp)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: SponsorFeeTransaction): Array[Byte] = {
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(Array(0: Byte, tx.typeId, tx.version), this.bodyBytes(tx), tx.proofs.bytes()) // [typeId, version] appears twice
  }

  def parseBytes(bytes: Array[Byte]): Try[SponsorFeeTransaction] = Try {
    require(bytes.length > 2, "buffer underflow while parsing transaction")

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == 0 && buf.getByte == SponsorFeeTransaction.typeId && buf.getByte == TxVersion.V1, "transaction type mismatch")
    require(buf.getByte == SponsorFeeTransaction.typeId && buf.getByte == TxVersion.V1, "transaction type mismatch")

    val sender               = buf.getPublicKey
    val asset                = buf.getIssuedAsset
    val minSponsoredAssetFee = buf.getLong
    val fee                  = buf.getLong
    val timestamp            = buf.getLong
    val proofs               = buf.getProofs
    SponsorFeeTransaction(TxVersion.V1, sender, asset, Some(minSponsoredAssetFee).filterNot(_ == 0), fee, timestamp, proofs, AddressScheme.current.chainId)
  }
} 
Example 175
Source File: BaseTxJson.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import com.wavesplatform.transaction.{LegacyPBSwitch, ProvenTransaction, SigProofsSwitch, VersionedTransaction}
import play.api.libs.json.{JsArray, JsObject, JsString, Json}

object BaseTxJson {
  def toJson(tx: ProvenTransaction): JsObject = {
    import tx._
    Json.obj(
      "type"            -> typeId,
      "id"              -> id().toString,
      "sender"          -> sender.toAddress,
      "senderPublicKey" -> sender,
      "fee"             -> assetFee._2,
      "feeAssetId"      -> assetFee._1.maybeBase58Repr,
      "timestamp"       -> timestamp,
      "proofs"          -> JsArray(proofs.proofs.map(p => JsString(p.toString)))
    ) ++ (tx match {
      // Compatibility
      case s: SigProofsSwitch if s.usesLegacySignature => Json.obj("signature" -> tx.signature.toString)
      case _                                           => Json.obj()
    }) ++ (tx match {
      case v: VersionedTransaction => Json.obj("version" -> v.version)
      case _                       => Json.obj()
    }) ++ (tx match {
      case pbs: LegacyPBSwitch if pbs.isProtobufVersion => Json.obj("chainId" -> tx.chainId)
      case _                                            => Json.obj()
    })
  }
} 
Example 176
Source File: SetScriptTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization.{ByteBufferOps, Deser}
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.smart.SetScriptTransaction
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object SetScriptTxSerializer {
  def toJson(tx: SetScriptTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "script" -> script.map(_.bytes().base64)
    ) ++ (if (tx.version == TxVersion.V1) Json.obj("chainId" -> chainId) else Json.obj())
  }

  def bodyBytes(tx: SetScriptTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        Bytes.concat(
          Array(builder.typeId, version, chainId),
          sender.arr,
          Deser.serializeOptionOfArrayWithLength(script)(s => s.bytes().arr),
          Longs.toByteArray(fee),
          Longs.toByteArray(timestamp)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: SetScriptTransaction): Array[Byte] = {
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
  }

  def parseBytes(bytes: Array[Byte]): Try[SetScriptTransaction] = Try {
    require(bytes.length > 2, "buffer underflow while parsing transaction")

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == 0 && buf.getByte == SetScriptTransaction.typeId && buf.getByte == TxVersion.V1, "transaction type mismatch")
    require(buf.getByte == AddressScheme.current.chainId, "transaction chainId mismatch")

    val sender    = buf.getPublicKey
    val script    = buf.getScript
    val fee       = buf.getLong
    val timestamp = buf.getLong
    val proofs    = buf.getProofs
    SetScriptTransaction(TxVersion.V1, sender, script, fee, timestamp, proofs, AddressScheme.current.chainId)
  }
} 
Example 177
Source File: LeaseCancelTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.crypto
import com.wavesplatform.serialization.ByteBufferOps
import com.wavesplatform.transaction.lease.LeaseCancelTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object LeaseCancelTxSerializer {
  def toJson(tx: LeaseCancelTransaction): JsObject =
    BaseTxJson.toJson(tx) ++ Json.obj("leaseId" -> tx.leaseId.toString) ++
      (if (tx.version == TxVersion.V2) Json.obj("chainId" -> tx.chainId) else Json.obj())

  def bodyBytes(tx: LeaseCancelTransaction): Array[Byte] = {
    import tx._
    val baseBytes = Bytes.concat(sender.arr, Longs.toByteArray(fee), Longs.toByteArray(timestamp), leaseId.arr)

    version match {
      case TxVersion.V1 => Bytes.concat(Array(typeId), baseBytes)
      case TxVersion.V2 => Bytes.concat(Array(typeId, version, chainId), baseBytes)
      case _            => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: LeaseCancelTransaction): Array[Byte] = {
    tx.version match {
      case TxVersion.V1 => Bytes.concat(this.bodyBytes(tx), tx.proofs.toSignature.arr)
      case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
      case _            => PBTransactionSerializer.bytes(tx)
    }
  }

  def parseBytes(bytes: Array[Byte]): Try[LeaseCancelTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): LeaseCancelTransaction = {
      val sender    = buf.getPublicKey
      val fee       = buf.getLong
      val timestamp = buf.getLong
      val leaseId   = buf.getByteArray(crypto.DigestLength)
      LeaseCancelTransaction(version, sender, ByteStr(leaseId), fee, timestamp, Nil, AddressScheme.current.chainId)
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == LeaseCancelTransaction.typeId, "transaction type mismatch")
      require(bytes(2) == TxVersion.V2, "transaction version mismatch")
      val buf = ByteBuffer.wrap(bytes, 4, bytes.length - 4)
      parseCommonPart(TxVersion.V2, buf).copy(proofs = buf.getProofs)
    } else {
      require(bytes(0) == LeaseCancelTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(buf.getSignature))
    }
  }
} 
Example 178
Source File: TransferTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.serialization.{ByteBufferOps, Deser}
import com.wavesplatform.transaction.transfer.TransferTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import com.wavesplatform.utils.byteStrFormat
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object TransferTxSerializer {
  def toJson(tx: TransferTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "recipient"  -> recipient.stringRepr,
      "assetId"    -> assetId.maybeBase58Repr,
      "feeAsset"   -> feeAssetId.maybeBase58Repr, // legacy v0.11.1 compat
      "amount"     -> amount,
      "attachment" -> attachment
    )
  }

  def bodyBytes(tx: TransferTransaction): Array[Byte] = {
    import tx._
    lazy val baseBytes =
      Bytes.concat(
        sender.arr,
        assetId.byteRepr,
        feeAssetId.byteRepr,
        Longs.toByteArray(timestamp),
        Longs.toByteArray(amount),
        Longs.toByteArray(fee),
        recipient.bytes,
        Deser.serializeArrayWithLength(attachment.arr)
      )

    version match {
      case TxVersion.V1 => Bytes.concat(Array(typeId), baseBytes)
      case TxVersion.V2 => Bytes.concat(Array(typeId, version), baseBytes)
      case _            => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: TransferTransaction): Array[Byte] = tx.version match {
    case TxVersion.V1 => Bytes.concat(Array(tx.typeId), tx.proofs.toSignature.arr, this.bodyBytes(tx))
    case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
    case _            => PBTransactionSerializer.bytes(tx)
  }

  def parseBytes(bytes: Array[Byte]): Try[TransferTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): TransferTransaction = {
      val sender     = buf.getPublicKey
      val assetId    = buf.getAsset
      val feeAssetId = buf.getAsset
      val ts         = buf.getLong
      val amount     = buf.getLong
      val fee        = buf.getLong
      val recipient  = buf.getAddressOrAlias
      val attachment = buf.getByteArrayWithLength

      TransferTransaction(version, sender, recipient, assetId, amount, feeAssetId, fee, ByteStr(attachment), ts, Proofs.empty, recipient.chainId)
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == TransferTransaction.typeId, "transaction type mismatch")
      val buf    = ByteBuffer.wrap(bytes, 3, bytes.length - 3)
      val tx     = parseCommonPart(TxVersion.V2, buf)
      val proofs = buf.getProofs
      tx.copy(proofs = proofs)
    } else {
      require(bytes(0) == TransferTransaction.typeId, "transaction type mismatch")
      val buf       = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      val signature = buf.getSignature
      require(buf.get == TransferTransaction.typeId, "transaction type mismatch")
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(signature))
    }
  }
} 
Example 179
Source File: IssueTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.serialization.{ByteBufferOps, Deser}
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object IssueTxSerializer {
  def toJson(tx: IssueTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "assetId"     -> id().toString,
      "name"        -> name.toStringUtf8,
      "quantity"    -> quantity,
      "reissuable"  -> reissuable,
      "decimals"    -> decimals,
      "description" -> description.toStringUtf8
    ) ++ (if (version >= TxVersion.V2) Json.obj("script" -> script.map(_.bytes().base64)) else JsObject.empty) ++
      (if (version == TxVersion.V2) Json.obj("chainId"   -> chainId) else JsObject.empty)
  }

  def bodyBytes(tx: IssueTransaction): Array[Byte] = {
    import tx._
    lazy val baseBytes = Bytes.concat(
      sender.arr,
      Deser.serializeArrayWithLength(name.toByteArray),
      Deser.serializeArrayWithLength(description.toByteArray),
      Longs.toByteArray(quantity),
      Array(decimals),
      Deser.serializeBoolean(reissuable),
      Longs.toByteArray(fee),
      Longs.toByteArray(timestamp)
    )

    version match {
      case TxVersion.V1 => Bytes.concat(Array(typeId), baseBytes)
      case TxVersion.V2 =>
        Bytes.concat(Array(builder.typeId, version, chainId), baseBytes, Deser.serializeOptionOfArrayWithLength(script)(_.bytes().arr))
      case _ => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: IssueTransaction): Array[Byte] =
    tx.version match {
      case TxVersion.V1 => Bytes.concat(Array(tx.typeId), tx.proofs.toSignature.arr, this.bodyBytes(tx)) // Signature before body, typeId appears twice
      case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
      case _            => PBTransactionSerializer.bytes(tx)
    }

  def parseBytes(bytes: Array[Byte]): Try[IssueTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): IssueTransaction = {
      val sender      = buf.getPublicKey
      val name        = Deser.parseArrayWithLength(buf)
      val description = Deser.parseArrayWithLength(buf)
      val quantity    = buf.getLong
      val decimals    = buf.getByte
      val reissuable  = buf.getBoolean
      val fee         = buf.getLong
      val timestamp   = buf.getLong
      IssueTransaction(
        version,
        sender,
        name,
        description,
        quantity,
        decimals,
        reissuable,
        None,
        fee,
        timestamp,
      )
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == IssueTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 4, bytes.length - 4)
      parseCommonPart(TxVersion.V2, buf).copy(script = buf.getScript, proofs = buf.getProofs)
    } else {
      require(bytes(0) == IssueTransaction.typeId, "transaction type mismatch")
      val buf       = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      val signature = buf.getSignature
      require(buf.getByte == IssueTransaction.typeId, "transaction type mismatch")
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(signature))
    }
  }
} 
Example 180
Source File: PaymentTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Ints, Longs}
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.PaymentTransaction
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object PaymentTxSerializer {
  def toJson(tx: PaymentTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj("recipient" -> recipient.stringRepr, "amount" -> amount)
  }

  def hashBytes(tx: PaymentTransaction): Array[Byte] = {
    import tx._
    Bytes.concat(
      Array(builder.typeId),
      Longs.toByteArray(timestamp),
      sender.arr,
      recipient.bytes,
      Longs.toByteArray(amount),
      Longs.toByteArray(fee)
    )
  }

  def bodyBytes(tx: PaymentTransaction): Array[Byte] = {
    import tx._
    Bytes.concat(
      Ints.toByteArray(builder.typeId), // 4 bytes
      Longs.toByteArray(timestamp),
      sender.arr,
      recipient.bytes,
      Longs.toByteArray(amount),
      Longs.toByteArray(fee)
    )
  }

  def toBytes(tx: PaymentTransaction): Array[Byte] = {
    Bytes.concat(this.hashBytes(tx), tx.signature.arr)
  }

  def parseBytes(bytes: Array[Byte]): Try[PaymentTransaction] = Try {
    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == PaymentTransaction.typeId, "transaction type mismatch")
    val timestamp = buf.getLong
    val sender    = buf.getPublicKey
    val recipient = buf.getAddress
    val amount    = buf.getLong
    val fee       = buf.getLong
    val signature = buf.getSignature
    PaymentTransaction(sender, recipient, amount, fee, timestamp, signature, recipient.chainId)
  }
} 
Example 181
Source File: CreateAliasTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.serialization.{ByteBufferOps, Deser}
import com.wavesplatform.transaction.{CreateAliasTransaction, Proofs, Transaction, TxVersion}
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object CreateAliasTxSerializer {
  def toJson(tx: CreateAliasTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj("alias" -> aliasName)
  }

  def bodyBytes(tx: CreateAliasTransaction): Array[Byte] = {
    import tx._

    lazy val base = Bytes.concat(
      sender.arr,
      Deser.serializeArrayWithLength(alias.bytes),
      Longs.toByteArray(fee),
      Longs.toByteArray(timestamp)
    )

    version match {
      case TxVersion.V1 => Bytes.concat(Array(builder.typeId), base)
      case TxVersion.V2 => Bytes.concat(Array(builder.typeId, version), base)
      case _            => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: CreateAliasTransaction): Array[Byte] = tx.version match {
    case TxVersion.V1 => Bytes.concat(this.bodyBytes(tx), tx.signature.arr)
    case TxVersion.V2 => Bytes.concat(Array(0: Byte), this.bodyBytes(tx), tx.proofs.bytes())
    case _            => PBTransactionSerializer.bytes(tx)
  }

  def parseBytes(bytes: Array[Byte]): Try[CreateAliasTransaction] = Try {
    require(bytes.length > 3, "buffer underflow while parsing transaction")
    bytes.take(3) match {
      case Array(CreateAliasTransaction.typeId, _, _) =>
        val buf       = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
        val sender    = buf.getPublicKey
        val alias     = buf.getAlias
        val fee       = buf.getLong
        val timestamp = buf.getLong
        val signature = buf.getSignature
        CreateAliasTransaction(Transaction.V1, sender, alias.name, fee, timestamp, Proofs(signature), alias.chainId)

      case Array(0, CreateAliasTransaction.typeId, 2) =>
        val buf       = ByteBuffer.wrap(bytes, 3, bytes.length - 3)
        val sender    = buf.getPublicKey
        val alias     = buf.getAlias
        val fee       = buf.getLong
        val timestamp = buf.getLong
        val proofs    = buf.getProofs
        CreateAliasTransaction(Transaction.V2, sender, alias.name, fee, timestamp, proofs, alias.chainId)

      case Array(b1, b2, b3) => throw new IllegalArgumentException(s"Invalid tx header bytes: $b1, $b2, $b3")
    }
  }
} 
Example 182
Source File: BurnTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.AddressScheme
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.assets.BurnTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import monix.eval.Coeval
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object BurnTxSerializer {
  def toJson(tx: BurnTransaction): Coeval[JsObject] = Coeval.evalOnce {
    import tx._
    BaseTxJson.toJson(tx) ++
      Json.obj("assetId" -> asset.id.toString, (if (version < TxVersion.V3) "amount" else "quantity") -> quantity) ++
      (if (version == TxVersion.V2) Json.obj("chainId" -> chainId) else JsObject.empty)
  }

  def bodyBytes(tx: BurnTransaction): Coeval[Array[Byte]] = Coeval.evalOnce {
    import tx._
    lazy val baseBytes = Bytes.concat(
      sender.arr,
      asset.id.arr,
      Longs.toByteArray(quantity),
      Longs.toByteArray(fee),
      Longs.toByteArray(timestamp)
    )

    version match {
      case TxVersion.V1 => Bytes.concat(Array(typeId), baseBytes)
      case TxVersion.V2 => Bytes.concat(Array(builder.typeId, version, chainId), baseBytes)
      case _            => PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: BurnTransaction): Coeval[Array[Byte]] = tx.version match {
    case TxVersion.V1 => tx.bodyBytes.map(bb => Bytes.concat(bb, tx.proofs.toSignature.arr))
    case TxVersion.V2 => tx.bodyBytes.map(bb => Bytes.concat(Array(0: Byte), bb, tx.proofs.bytes()))
    case _            => Coeval.evalOnce(PBTransactionSerializer.bytes(tx))
  }

  def parseBytes(bytes: Array[Byte]): Try[BurnTransaction] = Try {
    def parseCommonPart(version: TxVersion, buf: ByteBuffer): BurnTransaction = {
      val sender    = buf.getPublicKey
      val asset     = buf.getIssuedAsset
      val quantity  = buf.getLong
      val fee       = buf.getLong
      val timestamp = buf.getLong
      BurnTransaction(version, sender, asset, quantity, fee, timestamp, Nil, AddressScheme.current.chainId)
    }

    require(bytes.length > 2, "buffer underflow while parsing transaction")

    if (bytes(0) == 0) {
      require(bytes(1) == BurnTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 4, bytes.length - 4)
      parseCommonPart(TxVersion.V2, buf).copy(proofs = buf.getProofs)
    } else {
      require(bytes(0) == BurnTransaction.typeId, "transaction type mismatch")
      val buf = ByteBuffer.wrap(bytes, 1, bytes.length - 1)
      parseCommonPart(TxVersion.V1, buf).copy(proofs = Proofs(buf.getSignature))
    }
  }
} 
Example 183
Source File: MassTransferTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs, Shorts}
import com.wavesplatform.account.{AddressOrAlias, AddressScheme}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils._
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.transfer.MassTransferTransaction
import com.wavesplatform.transaction.transfer.MassTransferTransaction.{ParsedTransfer, Transfer}
import com.wavesplatform.utils.byteStrFormat
import play.api.libs.json.{JsObject, JsValue, Json}

import scala.util.Try

object MassTransferTxSerializer {
  def transfersJson(transfers: Seq[ParsedTransfer]): JsValue =
    Json.toJson(transfers.map { case ParsedTransfer(address, amount) => Transfer(address.stringRepr, amount) })

  def toJson(tx: MassTransferTransaction): JsObject = {
    import tx._
    BaseTxJson.toJson(tx) ++ Json.obj(
      "assetId"       -> assetId.maybeBase58Repr,
      "attachment"    -> attachment,
      "transferCount" -> transfers.size,
      "totalAmount"   -> transfers.map(_.amount).sum,
      "transfers"     -> transfersJson(transfers)
    )
  }

  def bodyBytes(tx: MassTransferTransaction): Array[Byte] = {
    import tx._
    version match {
      case TxVersion.V1 =>
        val transferBytes = transfers.map { case ParsedTransfer(recipient, amount) => Bytes.concat(recipient.bytes, Longs.toByteArray(amount)) }

        Bytes.concat(
          Array(builder.typeId, version),
          sender.arr,
          assetId.byteRepr,
          Shorts.toByteArray(transfers.size.toShort),
          Bytes.concat(transferBytes: _*),
          Longs.toByteArray(timestamp),
          Longs.toByteArray(fee),
          Deser.serializeArrayWithLength(attachment.arr)
        )

      case _ =>
        PBTransactionSerializer.bodyBytes(tx)
    }
  }

  def toBytes(tx: MassTransferTransaction): Array[Byte] =
    if (tx.isProtobufVersion) PBTransactionSerializer.bytes(tx)
    else Bytes.concat(this.bodyBytes(tx), tx.proofs.bytes()) // No zero mark

  def parseBytes(bytes: Array[Byte]): Try[MassTransferTransaction] = Try {
    def parseTransfers(buf: ByteBuffer): Seq[MassTransferTransaction.ParsedTransfer] = {
      def readTransfer(buf: ByteBuffer): ParsedTransfer = {
        val addressOrAlias = AddressOrAlias.fromBytes(buf).explicitGet()
        val amount         = buf.getLong
        ParsedTransfer(addressOrAlias, amount)
      }

      val entryCount = buf.getShort
      require(entryCount >= 0 && buf.remaining() > entryCount, s"Broken array size ($entryCount entries while ${buf.remaining()} bytes available)")
      Vector.fill(entryCount)(readTransfer(buf))
    }

    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == MassTransferTransaction.typeId && buf.getByte == TxVersion.V1, "transaction type mismatch")

    val sender     = buf.getPublicKey
    val assetId    = buf.getAsset
    val transfers  = parseTransfers(buf)
    val timestamp  = buf.getLong // Timestamp before fee
    val fee        = buf.getLong
    val attachment = Deser.parseArrayWithLength(buf)
    val proofs     = buf.getProofs
    MassTransferTransaction(TxVersion.V1, sender, assetId, transfers, fee, timestamp, ByteStr(attachment), proofs, AddressScheme.current.chainId)
  }
} 
Example 184
Source File: GenesisTxSerializer.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.serialization.impl

import java.nio.ByteBuffer

import com.google.common.primitives.{Bytes, Longs}
import com.wavesplatform.account.Address
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.serialization._
import com.wavesplatform.transaction.GenesisTransaction
import play.api.libs.json.{JsObject, Json}

import scala.util.Try

object GenesisTxSerializer {
  val BaseLength: Int = Address.AddressLength + Longs.BYTES * 2

  def toJson(tx: GenesisTransaction): JsObject = {
    import tx._
    Json.obj(
      "type"      -> builder.typeId,
      "id"        -> id().toString,
      "fee"       -> 0,
      "timestamp" -> timestamp,
      "signature" -> signature.toString,
      "recipient" -> recipient.stringRepr,
      "amount"    -> amount
    )
  }

  def toBytes(tx: GenesisTransaction): Array[Byte] = {
    import tx._
    val typeBytes      = Array(builder.typeId)
    val timestampBytes = Longs.toByteArray(timestamp)
    val rcpBytes       = recipient.bytes
    val amountBytes    = Longs.toByteArray(amount)
    require(rcpBytes.length == Address.AddressLength)
    val res = Bytes.concat(typeBytes, timestampBytes, rcpBytes, amountBytes)
    require(res.length == BaseLength + 1)
    res
  }

  def parseBytes(bytes: Array[Byte]): Try[GenesisTransaction] = Try {
    val buf = ByteBuffer.wrap(bytes)
    require(buf.getByte == GenesisTransaction.typeId, "transaction type mismatch")
    val timestamp = buf.getLong
    val recipient = buf.getAddress
    val amount    = buf.getLong
    GenesisTransaction(recipient, amount, timestamp, ByteStr(GenesisTransaction.generateSignature(recipient, amount, timestamp)), recipient.chainId)
  }
} 
Example 185
Source File: TracedResult.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.smart.script.trace

import cats.implicits._
import cats.{Applicative, Apply, Functor}
import cats.kernel.Semigroup
import com.wavesplatform.api.http.ApiError
import com.wavesplatform.transaction.Transaction
import play.api.libs.json.{JsObject, Json}

final case class TracedResult[+E, +A](
    resultE: Either[E, A],
    trace: List[TraceStep] = Nil
) {
  def transformE[B, E1](f: Either[E, A] => TracedResult[E1, B]): TracedResult[E1, B] = {
    val newResultE = f(resultE)
    newResultE.copy(trace = this.trace ::: newResultE.trace)
  }

  def flatMap[B, E1 >: E](f: A => TracedResult[E1, B]): TracedResult[E1, B] = {
    resultE match {
      case Left(_) => this.asInstanceOf[TracedResult[E1, B]]
      case Right(value) =>
        val newResult = f(value)
        newResult.copy(trace = this.trace ::: newResult.trace)
    }
  }

  def map[B](f: A => B): TracedResult[E, B] = copy(resultE.map(f))

  def leftMap[E1](f: E => E1): TracedResult[E1, A] = copy(resultE.leftMap(f))

  def json(implicit ev1: E => ApiError, ev2: A => Transaction): JsObject = {
    val resultJson = resultE match {
      case Right(value) => value.json()
      case Left(e)      => e.json
    }
    resultJson ++ Json.obj("trace" -> trace.map(_.json))
  }

  def loggedJson(implicit ev1: E => ApiError, ev2: A => Transaction): JsObject = {
    val resultJson = resultE match {
      case Right(value) => value.json()
      case Left(e)      => e.json
    }
    resultJson ++ Json.obj("trace" -> trace.map(_.loggedJson))
  }
}

object TracedResult {
  implicit def wrapE[A, E](e: Either[E, A]): TracedResult[E, A] = TracedResult(e)

  implicit def wrapValue[A, E](value: A): TracedResult[E, A] = TracedResult(Right(value))

  implicit def tracedResultSemigroup[A: Semigroup, E]: Semigroup[TracedResult[E, A]] =
    (a, b) =>
      TracedResult(
        a.resultE |+| b.resultE,
        if (a.resultE.isRight) a.trace |+| b.trace else a.trace
      )

  implicit def applicativeTracedResult[L]: Applicative[TracedResult[L, ?]] with Apply[TracedResult[L, ?]] with Functor[TracedResult[L, ?]]  = new Applicative[TracedResult[L, ?]] {
    def pure[A](v:A) = wrapValue[A, L](v)
    def ap[A,B](fb: TracedResult[L, A=>B])(fa: TracedResult[L, A]) : TracedResult[L, B] = {
      TracedResult(fa.resultE ap fb.resultE, fa.trace ++ fb.trace)
    }
    override def product[A,B](fa: TracedResult[L, A], fb: TracedResult[L, B]) : TracedResult[L, (A,B)] = {
      TracedResult(fa.resultE product fb.resultE, fa.trace ++ fb.trace)
    }
    override def map[A,B](x: TracedResult[L, A])(f: A=>B) : TracedResult[L, B] = {
      TracedResult[L,B](x.resultE map f, x.trace)
    }
  }
} 
Example 186
Source File: AssetPair.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.assets.exchange

import com.google.common.primitives.Bytes
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.serialization.Deser
import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves}
import com.wavesplatform.transaction._
import com.wavesplatform.transaction.assets.exchange.Validation.booleanOperators
import net.ceedubs.ficus.readers.ValueReader
import play.api.libs.json.{JsObject, Json}

import scala.util.{Failure, Success, Try}


case class AssetPair(
     amountAsset: Asset,
     priceAsset: Asset
) {
  import AssetPair._

  lazy val priceAssetStr: String  = assetIdStr(priceAsset)
  lazy val amountAssetStr: String = assetIdStr(amountAsset)
  override def toString: String   = key
  def key: String                 = amountAssetStr + "-" + priceAssetStr
  def isValid: Validation         = (amountAsset != priceAsset) :| "Invalid AssetPair"
  def bytes: Array[Byte]          = Bytes.concat(amountAsset.byteRepr, priceAsset.byteRepr)
  def json: JsObject = Json.obj(
    "amountAsset" -> amountAsset.maybeBase58Repr,
    "priceAsset"  -> priceAsset.maybeBase58Repr
  )
  def reverse = AssetPair(priceAsset, amountAsset)

  def assets: Set[Asset] = Set(amountAsset, priceAsset)
}

object AssetPair {
  val WavesName = "WAVES"

  def assetIdStr(aid: Asset): String = aid match {
    case Waves           => WavesName
    case IssuedAsset(id) => id.toString
  }

  def extractAssetId(a: String): Try[Asset] = a match {
    case `WavesName` => Success(Waves)
    case other       => ByteStr.decodeBase58(other).map(IssuedAsset)
  }

  def createAssetPair(amountAsset: String, priceAsset: String): Try[AssetPair] =
    for {
      a1 <- extractAssetId(amountAsset)
      a2 <- extractAssetId(priceAsset)
    } yield AssetPair(a1, a2)

  def fromBytes(xs: Array[Byte]): AssetPair = {
    val (amount, offset) = Deser.parseByteArrayOption(xs, 0, AssetIdLength)
    val (price, _)       = Deser.parseByteArrayOption(xs, offset, AssetIdLength)
    AssetPair(
      Asset.fromCompatId(amount.map(ByteStr(_))),
      Asset.fromCompatId(price.map(ByteStr(_)))
    )
  }

  def fromString(s: String): Try[AssetPair] = Try(s.split("-")).flatMap {
    case Array(amtAssetStr, prcAssetStr) => AssetPair.createAssetPair(amtAssetStr, prcAssetStr)
    case xs                              => Failure(new Exception(s"$s (incorrect assets count, expected 2 but got ${xs.size}: ${xs.mkString(", ")})"))
  }

  implicit val assetPairReader: ValueReader[AssetPair] = (cfg, path) => fromString(cfg.getString(path)).get
} 
Example 187
Source File: AliasApiRoute.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.alias

import akka.NotUsed
import akka.http.scaladsl.common.{EntityStreamingSupport, JsonEntityStreamingSupport}
import akka.http.scaladsl.server.Route
import akka.stream.scaladsl.Source
import cats.syntax.either._
import com.wavesplatform.account.Alias
import com.wavesplatform.api.common.CommonTransactionsApi
import com.wavesplatform.api.http._
import com.wavesplatform.api.http.requests.CreateAliasRequest
import com.wavesplatform.http.BroadcastRoute
import com.wavesplatform.network.UtxPoolSynchronizer
import com.wavesplatform.settings.RestAPISettings
import com.wavesplatform.state.Blockchain
import com.wavesplatform.transaction._
import com.wavesplatform.utils.Time
import com.wavesplatform.wallet.Wallet
import play.api.libs.json.{JsString, JsValue, Json}

case class AliasApiRoute(
    settings: RestAPISettings,
    commonApi: CommonTransactionsApi,
    wallet: Wallet,
    utxPoolSynchronizer: UtxPoolSynchronizer,
    time: Time,
    blockchain: Blockchain
) extends ApiRoute
    with BroadcastRoute
    with AuthRoute {

  override val route: Route = pathPrefix("alias") {
    addressOfAlias ~ aliasOfAddress ~ deprecatedRoute
  }

  private def deprecatedRoute: Route =
    path("broadcast" / "create") {
      broadcast[CreateAliasRequest](_.toTx)
    } ~ (path("create") & withAuth) {
      broadcast[CreateAliasRequest](TransactionFactory.createAlias(_, wallet, time))
    }

  def addressOfAlias: Route = (get & path("by-alias" / Segment)) { aliasName =>
    complete {
      Alias
        .create(aliasName)
        .flatMap { a =>
          blockchain.resolveAlias(a).bimap(_ => TxValidationError.AliasDoesNotExist(a), addr => Json.obj("address" -> addr.stringRepr))
        }
    }
  }

  private implicit val ess: JsonEntityStreamingSupport = EntityStreamingSupport.json()

  def aliasOfAddress: Route = (get & path("by-address" / AddrSegment)) { address =>
    extractScheduler { implicit s =>
      val value: Source[JsValue, NotUsed] =
        Source.fromPublisher(commonApi.aliasesOfAddress(address).map { case (_, tx) => JsString(tx.alias.stringRepr) }.toReactivePublisher)
      complete(value)
    }
  }
} 
Example 188
Source File: RewardApiRoute.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http

import akka.http.scaladsl.server.Route
import com.wavesplatform.features.BlockchainFeatures
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.state.Blockchain
import com.wavesplatform.transaction.TxValidationError.GenericError
import play.api.libs.json.{Format, Json}

case class RewardApiRoute(blockchain: Blockchain) extends ApiRoute {
  import RewardApiRoute._

  override lazy val route: Route = pathPrefix("blockchain" / "rewards") {
    rewards ~ rewardsAtHeight()
  }

  def rewards(): Route = (get & pathEndOrSingleSlash) {
    complete(getRewards(blockchain.height))
  }

  def rewardsAtHeight(): Route = (get & path(IntNumber)) { height =>
    complete(getRewards(height))
  }

  def getRewards(height: Int): Either[ValidationError, RewardStatus] =
    for {
      _ <- Either.cond(height <= blockchain.height, (), GenericError(s"Invalid height: $height"))
      activatedAt <- blockchain
        .featureActivationHeight(BlockchainFeatures.BlockReward.id)
        .filter(_ <= height)
        .toRight(GenericError("Block reward feature is not activated yet"))
      reward <- blockchain.blockReward(height).toRight(GenericError(s"No information about rewards at height = $height"))
      amount              = blockchain.wavesAmount(height)
      settings            = blockchain.settings.rewardsSettings
      nextCheck           = settings.nearestTermEnd(activatedAt, height)
      votingIntervalStart = nextCheck - settings.votingInterval + 1
      votingThreshold     = settings.votingInterval / 2 + 1
      votes               = blockchain.blockRewardVotes(height).filter(_ >= 0)
    } yield RewardStatus(
      height,
      amount,
      reward,
      settings.minIncrement,
      settings.term,
      nextCheck,
      votingIntervalStart,
      settings.votingInterval,
      votingThreshold,
      RewardVotes(votes.count(_ > reward), votes.count(_ < reward))
    )
}

object RewardApiRoute {
  final case class RewardStatus(
      height: Int,
      totalWavesAmount: BigInt,
      currentReward: Long,
      minIncrement: Long,
      term: Int,
      nextCheck: Int,
      votingIntervalStart: Int,
      votingInterval: Int,
      votingThreshold: Int,
      votes: RewardVotes
  )

  final case class RewardVotes(increase: Int, decrease: Int)

  implicit val rewardVotesFormat: Format[RewardVotes] = Json.format
  implicit val rewardFormat: Format[RewardStatus]     = Json.format
} 
Example 189
Source File: CompositeHttpService.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http

import akka.actor.ActorSystem
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpRequest, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.RouteResult.Complete
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.directives.{DebuggingDirectives, LoggingMagnet}
import com.wavesplatform.settings.RestAPISettings
import com.wavesplatform.utils.ScorexLogging

case class CompositeHttpService(routes: Seq[ApiRoute], settings: RestAPISettings)(system: ActorSystem) extends ScorexLogging {

  private val redirectToSwagger = redirect("/api-docs/index.html", StatusCodes.PermanentRedirect)
  private val swaggerRoute: Route =
    (pathEndOrSingleSlash | path("swagger"))(redirectToSwagger) ~
      pathPrefix("api-docs") {
        pathEndOrSingleSlash(redirectToSwagger) ~
          path("swagger.json")(complete(patchedSwaggerJson)) ~
          getFromResourceDirectory("swagger-ui")
      }

  val compositeRoute: Route        = extendRoute(routes.map(_.route).reduce(_ ~ _)) ~ swaggerRoute ~ complete(StatusCodes.NotFound)
  val loggingCompositeRoute: Route = Route.seal(DebuggingDirectives.logRequestResult(LoggingMagnet(_ => logRequestResponse))(compositeRoute))

  private def logRequestResponse(req: HttpRequest)(res: RouteResult): Unit = res match {
    case Complete(resp) =>
      val msg = s"HTTP ${resp.status.value} from ${req.method.value} ${req.uri}"
      if (resp.status == StatusCodes.OK) log.info(msg) else log.warn(msg)
    case _ =>
  }

  private val corsAllowedHeaders = (if (settings.apiKeyDifferentHost) List("api_key", "X-API-Key") else List.empty[String]) ++
    Seq("Authorization", "Content-Type", "X-Requested-With", "Timestamp", "Signature")

  private def corsAllowAll = if (settings.cors) respondWithHeader(`Access-Control-Allow-Origin`.*) else pass

  private def extendRoute(base: Route): Route = handleAllExceptions {
    if (settings.cors) { ctx =>
      val extendedRoute = corsAllowAll(base) ~ options {
        respondWithDefaultHeaders(
          `Access-Control-Allow-Credentials`(true),
          `Access-Control-Allow-Headers`(corsAllowedHeaders),
          `Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE)
        )(corsAllowAll(complete(StatusCodes.OK)))
      }

      extendedRoute(ctx)
    } else base
  }

  private[this] lazy val patchedSwaggerJson = {
    import com.wavesplatform.Version
    import com.wavesplatform.account.AddressScheme
    import play.api.libs.json.{JsObject, Json}

    def chainIdString: String =
      if (Character.isAlphabetic(AddressScheme.current.chainId)) AddressScheme.current.chainId.toChar.toString
      else s"#${AddressScheme.current.chainId}"

    val json = Json.parse(getClass.getClassLoader.getResourceAsStream("swagger-ui/swagger.json")).as[JsObject]
    val patchedInfo = (json \ "info").as[JsObject] ++ Json.obj(
      "version" -> Version.VersionString,
      "title"   -> s"Waves Full Node ($chainIdString)"
    )
    json ++ Json.obj("info" -> patchedInfo)
  }
} 
Example 190
Source File: SetAssetScriptRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.transaction.assets.SetAssetScriptTransaction
import play.api.libs.json.{Format, JsNumber, JsObject, Json}

case class SetAssetScriptRequest(
    version: Option[Byte],
    sender: String,
    assetId: String,
    script: Option[String],
    fee: Long,
    timestamp: Option[Long] = None
) {}

object SetAssetScriptRequest {
  implicit val jsonFormat: Format[SetAssetScriptRequest] = Json.format
  implicit class SetAssetScriptRequestExt(val self: SetAssetScriptRequest) extends AnyVal {
    def toJsObject: JsObject = Json.toJson(self).as[JsObject] + ("type" -> JsNumber(SetAssetScriptTransaction.typeId.toInt))
  }
} 
Example 191
Source File: SponsorFeeRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.assets.SponsorFeeTransaction
import com.wavesplatform.transaction.{AssetIdStringLength, Proofs}
import play.api.libs.json.{Format, Json}

object SponsorFeeRequest {
  implicit val unsignedSponsorRequestFormat: Format[SponsorFeeRequest]     = Json.format
  implicit val signedSponsorRequestFormat: Format[SignedSponsorFeeRequest] = Json.format
}

case class SponsorFeeRequest(
    version: Option[Byte],
    sender: String,
    assetId: String,
    minSponsoredAssetFee: Option[Long],
    fee: Long,
    timestamp: Option[Long] = None
)

case class SignedSponsorFeeRequest(
    version: Option[Byte],
    senderPublicKey: String,
    assetId: String,
    minSponsoredAssetFee: Option[Long],
    fee: Long,
    timestamp: Long,
    proofs: Proofs
) {
  def toTx: Either[ValidationError, SponsorFeeTransaction] =
    for {
      _sender <- PublicKey.fromBase58String(senderPublicKey)
      _asset  <- parseBase58(assetId, "invalid.assetId", AssetIdStringLength).map(IssuedAsset)
      t       <- SponsorFeeTransaction.create(version.getOrElse(1.toByte), _sender, _asset, minSponsoredAssetFee.filterNot(_ == 0), fee, timestamp, proofs)
    } yield t
} 
Example 192
Source File: CreateAliasRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.{CreateAliasTransaction, Proofs, TxAmount, TxTimestamp, TxVersion}
import play.api.libs.json.{Format, Json}

case class CreateAliasRequest(
    alias: String,
    version: Option[TxVersion] = None,
    sender: Option[String] = None,
    senderPublicKey: Option[String] = None,
    fee: Option[TxAmount] = None,
    timestamp: Option[TxTimestamp] = None,
    signature: Option[ByteStr] = None,
    proofs: Option[Proofs] = None
) extends TxBroadcastRequest {
  def toTxFrom(sender: PublicKey): Either[ValidationError, CreateAliasTransaction] =
    for {
      validProofs <- toProofs(signature, proofs)
      tx          <- CreateAliasTransaction.create(version.getOrElse(1.toByte), sender, alias, fee.getOrElse(0L), timestamp.getOrElse(0L), validProofs)
    } yield tx
}

object CreateAliasRequest {
  implicit val jsonFormat: Format[CreateAliasRequest] = Json.format
} 
Example 193
Source File: DataRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.state.DataEntry
import com.wavesplatform.transaction.{DataTransaction, Proofs}
import play.api.libs.json.{Format, Json}

object DataRequest {
  implicit val unsignedDataRequestReads: Format[DataRequest] = Json.format
}

case class DataRequest(
    version: Byte,
    sender: String,
    data: List[DataEntry[_]],
    fee: Long,
    timestamp: Option[Long] = None
)

case class SignedDataRequest(version: Byte, senderPublicKey: String, data: List[DataEntry[_]], fee: Long, timestamp: Long, proofs: Proofs) {
  def toTx: Either[ValidationError, DataTransaction] =
    for {
      _sender <- PublicKey.fromBase58String(senderPublicKey)
      t       <- DataTransaction.create(version, _sender, data, fee, timestamp, proofs)
    } yield t
}

object SignedDataRequest {
  implicit val signedDataRequestReads: Format[SignedDataRequest] = Json.format
} 
Example 194
Source File: IssueRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.lang.script.Script
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.{Proofs, TxVersion}
import play.api.libs.json.{Format, Json}

case class IssueRequest(
    version: Option[Byte],
    sender: Option[String],
    senderPublicKey: Option[String],
    name: String,
    description: String,
    quantity: Long,
    decimals: Byte,
    reissuable: Boolean,
    script: Option[String],
    fee: Long,
    timestamp: Option[Long],
    signature: Option[ByteStr],
    proofs: Option[Proofs]
) extends TxBroadcastRequest {
  def toTxFrom(sender: PublicKey): Either[ValidationError, IssueTransaction] = {
    val actualVersion = version.getOrElse(TxVersion.V3)

    for {
      validProofs <- toProofs(signature, proofs)
      validScript <- script match {
        case None         => Right(None)
        case Some(script) => Script.fromBase64String(script).map(Some(_))
      }
      tx <- IssueTransaction.create(
        actualVersion,
        sender,
        name,
        description,
        quantity,
        decimals,
        reissuable,
        validScript,
        fee,
        timestamp.getOrElse(defaultTimestamp),
        validProofs
      )
    } yield tx
  }
}

object IssueRequest {
  implicit val jsonFormat: Format[IssueRequest] = Json.format
} 
Example 195
Source File: MassTransferRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.transaction.transfer.MassTransferTransaction.Transfer
import play.api.libs.json.Json

case class MassTransferRequest(
    version: Option[Byte],
    assetId: Option[String],
    sender: String,
    transfers: List[Transfer],
    fee: Long,
    attachment: Option[ByteStr] = None,
    timestamp: Option[Long] = None
)

object MassTransferRequest {
  implicit val jsonFormat = Json.format[MassTransferRequest]
} 
Example 196
Source File: SignedUpdateAssetInfoRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import cats.implicits._
import com.wavesplatform.account.PublicKey
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves}
import com.wavesplatform.transaction.assets.UpdateAssetInfoTransaction
import com.wavesplatform.transaction.{AssetIdStringLength, Proofs, TxAmount, TxTimestamp, TxVersion}
import play.api.libs.json.{Format, Json}

case class SignedUpdateAssetInfoRequest(
    version: TxVersion,
    chainId: Byte,
    senderPublicKey: String,
    assetId: String,
    name: String,
    description: String,
    timestamp: TxTimestamp,
    fee: TxAmount,
    feeAssetId: Option[String],
    proofs: Proofs
) {

  def toTx: Either[ValidationError, UpdateAssetInfoTransaction] =
    for {
      _sender  <- PublicKey.fromBase58String(senderPublicKey)
      _assetId <- parseBase58(assetId, "invalid.assetId", AssetIdStringLength)
      _feeAssetId <- feeAssetId
        .traverse(parseBase58(_, "invalid.assetId", AssetIdStringLength).map(IssuedAsset))
        .map(_ getOrElse Waves)
      tx <- UpdateAssetInfoTransaction
        .create(version, _sender, _assetId, name, description, timestamp, fee, _feeAssetId, proofs, chainId)
    } yield tx

}

object SignedUpdateAssetInfoRequest {
  implicit val format: Format[SignedUpdateAssetInfoRequest] = Json.format
} 
Example 197
Source File: LeaseRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.{AddressOrAlias, PublicKey}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.Proofs
import com.wavesplatform.transaction.lease.LeaseTransaction
import play.api.libs.json.{Format, Json}

case class LeaseRequest(
    version: Option[Byte],
    sender: Option[String],
    senderPublicKey: Option[String],
    recipient: String,
    amount: Long,
    fee: Long,
    timestamp: Option[Long],
    signature: Option[ByteStr],
    proofs: Option[Proofs]
) extends TxBroadcastRequest {
  def toTxFrom(sender: PublicKey): Either[ValidationError, LeaseTransaction] =
    for {
      validRecipient <- AddressOrAlias.fromString(recipient)
      validProofs    <- toProofs(signature, proofs)
      tx <- LeaseTransaction.create(
        version.getOrElse(1.toByte),
        sender,
        validRecipient,
        amount,
        fee,
        timestamp.getOrElse(0L),
        validProofs
      )
    } yield tx
}

object LeaseRequest {
  implicit val jsonFormat: Format[LeaseRequest] = Json.format
} 
Example 198
Source File: ReissueRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.Asset.IssuedAsset
import com.wavesplatform.transaction.Proofs
import com.wavesplatform.transaction.assets.ReissueTransaction
import play.api.libs.json.{Format, Json}

case class ReissueRequest(
    version: Option[Byte],
    sender: Option[String],
    senderPublicKey: Option[String],
    assetId: IssuedAsset,
    quantity: Long,
    reissuable: Boolean,
    fee: Long,
    timestamp: Option[Long],
    signature: Option[ByteStr],
    proofs: Option[Proofs]
) extends TxBroadcastRequest {
  def toTxFrom(sender: PublicKey): Either[ValidationError, ReissueTransaction] =
    for {
      validProofs <- toProofs(signature, proofs)
      tx <- ReissueTransaction.create(
        version.getOrElse(defaultVersion),
        sender,
        assetId,
        quantity,
        reissuable,
        fee,
        timestamp.getOrElse(defaultTimestamp),
        validProofs
      )
    } yield tx
}

object ReissueRequest {
  implicit val jsonFormat: Format[ReissueRequest] = Json.format
} 
Example 199
Source File: ExchangeRequest.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api.http.requests

import com.wavesplatform.account.PublicKey
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.assets.exchange.{ExchangeTransaction, Order}
import com.wavesplatform.transaction.{Proofs, TxAmount, TxTimestamp, TxVersion}
import play.api.libs.json.{Format, Json}

case class ExchangeRequest(
    order1: Order,
    order2: Order,
    amount: Long,
    price: Long,
    buyMatcherFee: Long,
    sellMatcherFee: Long,
    version: Option[TxVersion] = None,
    sender: Option[String] = None,
    senderPublicKey: Option[String] = None,
    fee: Option[TxAmount] = None,
    timestamp: Option[TxTimestamp] = None,
    signature: Option[ByteStr] = None,
    proofs: Option[Proofs] = None
) extends TxBroadcastRequest {
  def toTxFrom(sender: PublicKey): Either[ValidationError, ExchangeTransaction] =
    for {
      validProofs <- toProofs(signature, proofs)
      tx <- ExchangeTransaction.create(
        version.getOrElse(1.toByte),
        order1,
        order2,
        amount,
        price,
        buyMatcherFee,
        sellMatcherFee,
        fee.getOrElse(0L),
        timestamp.getOrElse(0L),
        validProofs
      )
    } yield tx
}

object ExchangeRequest {
  implicit val jsonFormat: Format[ExchangeRequest] = Json.format
} 
Example 200
Source File: BlockMeta.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.api

import com.wavesplatform.block.Block.protoHeaderHash
import com.wavesplatform.block.serialization.BlockHeaderSerializer
import com.wavesplatform.block.{Block, BlockHeader, SignedBlockHeader}
import com.wavesplatform.common.state.ByteStr
import monix.eval.Coeval
import play.api.libs.json.{JsObject, Json}

case class BlockMeta(
    header: BlockHeader,
    signature: ByteStr,
    headerHash: Option[ByteStr],
    height: Int,
    size: Int,
    transactionCount: Int,
    totalFeeInWaves: Long,
    reward: Option[Long],
    vrf: Option[ByteStr]
) {
  def toSignedHeader: SignedBlockHeader = SignedBlockHeader(header, signature)
  def id: ByteStr                       = headerHash.getOrElse(signature)

  val json: Coeval[JsObject] = Coeval.evalOnce {
    BlockHeaderSerializer.toJson(header, size, transactionCount, signature) ++
      Json.obj("height" -> height, "totalFee" -> totalFeeInWaves) ++
      reward.fold(Json.obj())(r => Json.obj("reward" -> r)) ++
      vrf.fold(Json.obj())(v => Json.obj("VRF"       -> v.toString)) ++
      headerHash.fold(Json.obj())(h => Json.obj("id" -> h.toString))
  }
}

object BlockMeta {
  def fromBlock(block: Block, height: Int, totalFee: Long, reward: Option[Long], vrf: Option[ByteStr]): BlockMeta = BlockMeta(
    block.header,
    block.signature,
    if (block.header.version >= Block.ProtoBlockVersion) Some(protoHeaderHash(block.header)) else None,
    height,
    block.bytes().length,
    block.transactionData.length,
    totalFee,
    reward,
    vrf
  )
}