Skip to content

Commit

Permalink
RDB Loader: integrate Sentry (close #235)
Browse files Browse the repository at this point in the history
  • Loading branch information
chuwy committed Dec 10, 2020
1 parent 89c57ba commit 8b0ce82
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 123 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ lazy val loader = project.in(file("modules/loader"))
Dependencies.ssm,
Dependencies.dynamodb,
Dependencies.jSch,
Dependencies.sentry,

Dependencies.specs2,
Dependencies.specs2ScalaCheck,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package com.snowplowanalytics.snowplow.rdbloader.common

import java.net.URI
import java.util.UUID
import java.util.Properties

Expand Down Expand Up @@ -50,6 +51,7 @@ sealed trait StorageTarget extends Product with Serializable {

def blacklistTabular: Option[List[SchemaCriterion]] // None means tabular is disabled
def messageQueue: Option[String]
def sentryDsn: Option[URI]
}

object StorageTarget {
Expand Down Expand Up @@ -89,7 +91,8 @@ object StorageTarget {
sshTunnel: Option[TunnelConfig],

blacklistTabular: Option[List[SchemaCriterion]],
messageQueue: Option[String])
messageQueue: Option[String],
sentryDsn: Option[URI])
extends StorageTarget

/**
Expand Down Expand Up @@ -164,14 +167,28 @@ object StorageTarget {
case class DestinationConfig(host: String, port: Int)

/** ADT representing fact that password can be either plain-text or encrypted in EC2 Parameter Store */
sealed trait PasswordConfig {
sealed trait PasswordConfig extends Product with Serializable {
def getUnencrypted: String = this match {
case PlainText(plain) => plain
case EncryptedKey(EncryptedConfig(key)) => key.parameterName
case PasswordConfig.PlainText(plain) => plain
case PasswordConfig.EncryptedKey(EncryptedConfig(key)) => key.parameterName
}
}
object PasswordConfig {
final case class PlainText(value: String) extends PasswordConfig
final case class EncryptedKey(value: EncryptedConfig) extends PasswordConfig

implicit object PasswordDecoder extends Decoder[PasswordConfig] {
def apply(hCursor: HCursor): Decoder.Result[PasswordConfig] = {
hCursor.value.asString match {
case Some(s) => Right(PasswordConfig.PlainText(s))
case None => hCursor.value.asObject match {
case Some(_) => hCursor.value.as[EncryptedConfig].map(PasswordConfig.EncryptedKey)
case None => Left(DecodingFailure("password should be either plain text or reference to encrypted key", hCursor.history))
}
}
}
}
}
case class PlainText(value: String) extends PasswordConfig
case class EncryptedKey(value: EncryptedConfig) extends PasswordConfig

/**
* SSH configuration, enabling target to be loaded though tunnel
Expand All @@ -183,18 +200,6 @@ object StorageTarget {
*/
case class TunnelConfig(bastion: BastionConfig, localPort: Int, destination: DestinationConfig)

implicit object PasswordDecoder extends Decoder[PasswordConfig] {
def apply(hCursor: HCursor): Decoder.Result[PasswordConfig] = {
hCursor.value.asString match {
case Some(s) => Right(PlainText(s))
case None => hCursor.value.asObject match {
case Some(_) => hCursor.value.as[EncryptedConfig].map(EncryptedKey)
case None => Left(DecodingFailure("password should be either plain text or reference to encrypted key", hCursor.history))
}
}
}
}

/**
* Decode Json as one of known storage targets
*
Expand Down Expand Up @@ -222,6 +227,9 @@ object StorageTarget {
.toEitherNel
.flatMap { json => (decodeStorageTarget(json).toEitherNel, validate(client)(json).toEitherNel).parMapN { case (config, _) => config } }

implicit def uriDecoder: Decoder[URI] =
Decoder[String].emap(s => Either.catchOnly[IllegalArgumentException](URI.create(s)).leftMap(_.toString))

implicit def redsfhitConfigDecoder: Decoder[RedshiftConfig] =
deriveDecoder[RedshiftConfig]

Expand All @@ -240,9 +248,6 @@ object StorageTarget {
implicit def parameterStoreConfigDecoder: Decoder[ParameterStoreConfig] =
deriveDecoder[ParameterStoreConfig]

implicit def passwordConfigDecoder: Decoder[PasswordConfig] =
deriveDecoder[PasswordConfig]

implicit def schemaCriterionConfigDecoder: Decoder[SchemaCriterion] =
Decoder.decodeString.emap {
s => SchemaCriterion.parse(s).toRight(s"Cannot parse [$s] as Iglu SchemaCriterion, it must have iglu:vendor/name/format/1-*-* format")
Expand Down
Loading

0 comments on commit 8b0ce82

Please sign in to comment.