/** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.0.1-dev * User agent: apibuilder app.apibuilder.io/grhodes/code-deploy-dashboard/0.0.1-dev/http4s_0_22 */ package io.grhodes.code.deploy.dashboard.v0.models { /** * @param name Name of this application. * @param deploymentGroups List of deployment groups for this application. */ final case class Application( name: String, deploymentGroups: Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentGroup] ) /** * @param id The deployment id * @param created Date deployment created * @param started Date deployment started * @param completed Date deployment created * @param deploymentGroupName The deployment group name * @param failed The number of instances failed deployment * @param skipped The number of instances skipped deployment * @param inProgress The number of instances currently deploying * @param pending The number of instances pending deployment * @param succeeded The number of instances succeeded at deployment * @param status The status of the deployment * @param errorMessage A error message if the deployment failed * @param revisionLocation The location of the revision * @param instances The instances involved in this deployment */ final case class Deployment( id: String, created: _root_.java.time.Instant, started: _root_.java.time.Instant, completed: _root_.java.time.Instant, creator: String, deploymentGroupName: String, failed: Int, skipped: Int, inProgress: Int, pending: Int, succeeded: Int, status: String, errorMessage: _root_.scala.Option[String] = None, revisionLocation: String, instances: Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentInstance] ) /** * @param name Name of this deployment group. * @param autoScalingGroupNames List of auto scaling groups for this deployment group. */ final case class DeploymentGroup( name: String, autoScalingGroupNames: Seq[String] ) /** * @param id The instance id * @param status The status of this instances deployment * @param lastUpdatedAt Last updated at time * @param lifecycleEvents Deployment lifecycle events */ final case class DeploymentInstance( id: String, status: String, lastUpdatedAt: _root_.java.time.Instant, lifecycleEvents: Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentLifecycleEvent] ) /** * @param name The deployment lifecycle event name * @param startTime Time the deployment lifecycle event started * @param endTime Time the deployment lifecycle event ended * @param status The status of the deployment lifecycle event * @param errorLogTail The deployment lifecycle event log tail if it failed * @param errorMessage The deployment lifecycle event error message if it failed * @param scriptName The deployment lifecycle event script filename if it failed */ final case class DeploymentLifecycleEvent( name: String, startTime: _root_.java.time.Instant, endTime: _root_.java.time.Instant, status: String, errorLogTail: _root_.scala.Option[String] = None, errorMessage: _root_.scala.Option[String] = None, scriptName: _root_.scala.Option[String] = None ) /** * @param name Name of this service. * @param version Version of this service. * @param scalaVersion Version of Scala this service is using. * @param sbtVersion Version of SBT used to build this service. * @param buildTime Time the service was built at. */ final case class Info( name: String, version: String, scalaVersion: String, sbtVersion: String, buildTime: _root_.java.time.Instant ) } package io.grhodes.code.deploy.dashboard.v0.models { package object json { import io.circe.Decoder._ import io.circe.Encoder._ import scala.language.implicitConversions // See below - Make Scala 2.11 Either monadic import scala.util.Try import io.circe.{Json, JsonObject, Encoder, Decoder, DecodingFailure} import io.circe.syntax._ import io.grhodes.code.deploy.dashboard.v0.models.json._ // Make Scala 2.11 Either monadic private[v0] implicit def eitherOps[A,B](e: Either[A,B]) = cats.implicits.catsSyntaxEither(e) private[v0] implicit val decodeUUID: Decoder[_root_.java.util.UUID] = Decoder.decodeString.emapTry(str => Try(_root_.java.util.UUID.fromString(str))) private[v0] implicit val encodeUUID: Encoder[_root_.java.util.UUID] = Encoder.encodeString.contramap[_root_.java.util.UUID](uuid => uuid.toString) private[v0] implicit val decodeInstant: Decoder[_root_.java.time.Instant] = Decoder.decodeString.emapTry(str => Try(_root_.java.time.OffsetDateTime.parse(str).toInstant)) private[v0] implicit val encodeInstant: Encoder[_root_.java.time.Instant] = Encoder.encodeString.contramap[_root_.java.time.Instant](_.toString) private[v0] implicit val decodeLocalDate: Decoder[_root_.java.time.LocalDate] = Decoder.decodeString.emapTry(str => Try(_root_.java.time.LocalDate.parse(str))) private[v0] implicit val encodeLocalDate: Encoder[_root_.java.time.LocalDate] = Encoder.encodeString.contramap[_root_.java.time.LocalDate](_.toString) implicit def decodeCodeDeployDashboardApplication: Decoder[Application] = Decoder.instance { c => for { name <- c.downField("name").as[String] deploymentGroups <- c.downField("deploymentGroups").as[Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentGroup]] } yield { Application( name = name, deploymentGroups = deploymentGroups ) } } implicit def encodeCodeDeployDashboardApplication: Encoder[Application] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("deploymentGroups" -> t.deploymentGroups.asJson) ).flatten) } implicit def decodeCodeDeployDashboardDeployment: Decoder[Deployment] = Decoder.instance { c => for { id <- c.downField("id").as[String] created <- c.downField("created").as[_root_.java.time.Instant] started <- c.downField("started").as[_root_.java.time.Instant] completed <- c.downField("completed").as[_root_.java.time.Instant] creator <- c.downField("creator").as[String] deploymentGroupName <- c.downField("deployment_group_name").as[String] failed <- c.downField("failed").as[Int] skipped <- c.downField("skipped").as[Int] inProgress <- c.downField("in_progress").as[Int] pending <- c.downField("pending").as[Int] succeeded <- c.downField("succeeded").as[Int] status <- c.downField("status").as[String] errorMessage <- c.downField("error_message").as[Option[String]] revisionLocation <- c.downField("revision_location").as[String] instances <- c.downField("instances").as[Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentInstance]] } yield { Deployment( id = id, created = created, started = started, completed = completed, creator = creator, deploymentGroupName = deploymentGroupName, failed = failed, skipped = skipped, inProgress = inProgress, pending = pending, succeeded = succeeded, status = status, errorMessage = errorMessage, revisionLocation = revisionLocation, instances = instances ) } } implicit def encodeCodeDeployDashboardDeployment: Encoder[Deployment] = Encoder.instance { t => Json.fromFields(Seq( Some("id" -> t.id.asJson), Some("created" -> t.created.asJson), Some("started" -> t.started.asJson), Some("completed" -> t.completed.asJson), Some("creator" -> t.creator.asJson), Some("deployment_group_name" -> t.deploymentGroupName.asJson), Some("failed" -> t.failed.asJson), Some("skipped" -> t.skipped.asJson), Some("in_progress" -> t.inProgress.asJson), Some("pending" -> t.pending.asJson), Some("succeeded" -> t.succeeded.asJson), Some("status" -> t.status.asJson), t.errorMessage.map(t => "error_message" -> t.asJson), Some("revision_location" -> t.revisionLocation.asJson), Some("instances" -> t.instances.asJson) ).flatten) } implicit def decodeCodeDeployDashboardDeploymentGroup: Decoder[DeploymentGroup] = Decoder.instance { c => for { name <- c.downField("name").as[String] autoScalingGroupNames <- c.downField("autoScalingGroupNames").as[Seq[String]] } yield { DeploymentGroup( name = name, autoScalingGroupNames = autoScalingGroupNames ) } } implicit def encodeCodeDeployDashboardDeploymentGroup: Encoder[DeploymentGroup] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("autoScalingGroupNames" -> t.autoScalingGroupNames.asJson) ).flatten) } implicit def decodeCodeDeployDashboardDeploymentInstance: Decoder[DeploymentInstance] = Decoder.instance { c => for { id <- c.downField("id").as[String] status <- c.downField("status").as[String] lastUpdatedAt <- c.downField("last_updated_at").as[_root_.java.time.Instant] lifecycleEvents <- c.downField("lifecycle_events").as[Seq[io.grhodes.code.deploy.dashboard.v0.models.DeploymentLifecycleEvent]] } yield { DeploymentInstance( id = id, status = status, lastUpdatedAt = lastUpdatedAt, lifecycleEvents = lifecycleEvents ) } } implicit def encodeCodeDeployDashboardDeploymentInstance: Encoder[DeploymentInstance] = Encoder.instance { t => Json.fromFields(Seq( Some("id" -> t.id.asJson), Some("status" -> t.status.asJson), Some("last_updated_at" -> t.lastUpdatedAt.asJson), Some("lifecycle_events" -> t.lifecycleEvents.asJson) ).flatten) } implicit def decodeCodeDeployDashboardDeploymentLifecycleEvent: Decoder[DeploymentLifecycleEvent] = Decoder.instance { c => for { name <- c.downField("name").as[String] startTime <- c.downField("start_time").as[_root_.java.time.Instant] endTime <- c.downField("end_time").as[_root_.java.time.Instant] status <- c.downField("status").as[String] errorLogTail <- c.downField("error_log_tail").as[Option[String]] errorMessage <- c.downField("error_message").as[Option[String]] scriptName <- c.downField("script_name").as[Option[String]] } yield { DeploymentLifecycleEvent( name = name, startTime = startTime, endTime = endTime, status = status, errorLogTail = errorLogTail, errorMessage = errorMessage, scriptName = scriptName ) } } implicit def encodeCodeDeployDashboardDeploymentLifecycleEvent: Encoder[DeploymentLifecycleEvent] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("start_time" -> t.startTime.asJson), Some("end_time" -> t.endTime.asJson), Some("status" -> t.status.asJson), t.errorLogTail.map(t => "error_log_tail" -> t.asJson), t.errorMessage.map(t => "error_message" -> t.asJson), t.scriptName.map(t => "script_name" -> t.asJson) ).flatten) } implicit def decodeCodeDeployDashboardInfo: Decoder[Info] = Decoder.instance { c => for { name <- c.downField("name").as[String] version <- c.downField("version").as[String] scalaVersion <- c.downField("scala_version").as[String] sbtVersion <- c.downField("sbt_version").as[String] buildTime <- c.downField("build_time").as[_root_.java.time.Instant] } yield { Info( name = name, version = version, scalaVersion = scalaVersion, sbtVersion = sbtVersion, buildTime = buildTime ) } } implicit def encodeCodeDeployDashboardInfo: Encoder[Info] = Encoder.instance { t => Json.fromFields(Seq( Some("name" -> t.name.asJson), Some("version" -> t.version.asJson), Some("scala_version" -> t.scalaVersion.asJson), Some("sbt_version" -> t.sbtVersion.asJson), Some("build_time" -> t.buildTime.asJson) ).flatten) } } } package io.grhodes.code.deploy.dashboard.v0 { import cats.effect._ import cats.implicits._ import io.circe.syntax._ object Constants { val BaseUrl = "http://code-deploy-dashboard.tools.gilt.com" val Namespace = "io.grhodes.code.deploy.dashboard.v0" val UserAgent = "apibuilder app.apibuilder.io/grhodes/code-deploy-dashboard/0.0.1-dev/http4s_0_22" val Version = "0.0.1-dev" val VersionMajor = 0 } class Client[F[_]: Sync]( val baseUrl: org.http4s.Uri = org.http4s.Uri.unsafeFromString("http://code-deploy-dashboard.tools.gilt.com"), auth: scala.Option[io.grhodes.code.deploy.dashboard.v0.Authorization] = None, defaultHeaders: Seq[(String, String)] = Nil, httpClient: org.http4s.client.Client[F] ) extends interfaces.Client[F] { import org.http4s.Response import io.grhodes.code.deploy.dashboard.v0.models.json._ def applications: Applications[F] = Applications def info: Info[F] = Info object Applications extends Applications[F] { override def get( requestHeaders: Seq[(String, String)] = Nil ): F[Seq[io.grhodes.code.deploy.dashboard.v0.models.Application]] = { val urlPath = Seq("application") _executeRequest[Unit, Seq[io.grhodes.code.deploy.dashboard.v0.models.Application]]("GET", path = urlPath, requestHeaders = requestHeaders) { case r if r.status.code == 200 => _root_.io.grhodes.code.deploy.dashboard.v0.Client.parseJson[F, Seq[io.grhodes.code.deploy.dashboard.v0.models.Application]]("Seq[io.grhodes.code.deploy.dashboard.v0.models.Application]", r) case r => Sync[F].raiseError(new io.grhodes.code.deploy.dashboard.v0.errors.FailedRequest(r.status.code, s"Unsupported response code[${r.status.code}]. Expected: 200")) } } } object Info extends Info[F] { override def get( requestHeaders: Seq[(String, String)] = Nil ): F[io.grhodes.code.deploy.dashboard.v0.models.Info] = { val urlPath = Seq("info") _executeRequest[Unit, io.grhodes.code.deploy.dashboard.v0.models.Info]("GET", path = urlPath, requestHeaders = requestHeaders) { case r if r.status.code == 200 => _root_.io.grhodes.code.deploy.dashboard.v0.Client.parseJson[F, io.grhodes.code.deploy.dashboard.v0.models.Info]("io.grhodes.code.deploy.dashboard.v0.models.Info", r) case r => Sync[F].raiseError(new io.grhodes.code.deploy.dashboard.v0.errors.FailedRequest(r.status.code, s"Unsupported response code[${r.status.code}]. Expected: 200")) } } } private lazy val defaultApiHeaders = Seq( ("User-Agent", Constants.UserAgent), ("X-Apidoc-Version", Constants.Version), ("X-Apidoc-Version-Major", Constants.VersionMajor.toString) ) def apiHeaders: Seq[(String, String)] = defaultApiHeaders def modifyRequest(request: org.http4s.Request[F]): org.http4s.Request[F] = request implicit def circeJsonEncoder[F[_]: Sync, A](implicit encoder: io.circe.Encoder[A]) = org.http4s.circe.jsonEncoderOf[F, A] def _executeRequest[T, U]( method: String, path: Seq[String], queryParameters: Seq[(String, String)] = Nil, requestHeaders: Seq[(String, String)] = Nil, body: Option[T] = None, formBody : Option[org.http4s.UrlForm] = None )(handler: org.http4s.Response[F] => F[U] )(implicit encoder: io.circe.Encoder[T]): F[U] = { import org.http4s.QueryParamEncoder._ val m = org.http4s.Method.fromString(method) match { case Right(m) => m case Left(e) => sys.error(e.toString) } val headers = org.http4s.Headers(( apiHeaders ++ defaultHeaders ++ requestHeaders ).groupBy(_._1).map { case (k, l) => org.http4s.Header.Raw(org.typelevel.ci.CIString(k), l.last._2) }.toList) val queryMap = queryParameters.groupBy(_._1).map { case (k, v) => k -> v.map(_._2) } val uri = path.foldLeft(baseUrl){ case (uri, segment) => uri / segment }.setQueryParams(queryMap) val request = org.http4s.Request[F](method = m, uri = uri, headers = headers) val reqAndMaybeAuth = auth.fold(request) { case Authorization.Basic(username, passwordOpt) => { val userpass = s"$username:${passwordOpt.getOrElse("")}" val token = java.util.Base64.getEncoder.encodeToString(userpass.getBytes(java.nio.charset.StandardCharsets.ISO_8859_1)) request.putHeaders(org.http4s.Header.Raw(org.typelevel.ci.CIString("Authorization"), s"Basic $token")) } case a => sys.error("Invalid authorization scheme[" + a.getClass + "]") } val reqAndMaybeAuthAndBody = if (formBody.nonEmpty) formBody.fold(reqAndMaybeAuth)(reqAndMaybeAuth.withEntity) else body.fold(reqAndMaybeAuth)(reqAndMaybeAuth.withEntity) httpClient.fetch(modifyRequest(reqAndMaybeAuthAndBody))(handler) } } object Client { import cats.effect._ implicit def circeJsonDecoder[F[_]: Sync, A](implicit decoder: io.circe.Decoder[A]) = org.http4s.circe.jsonOf[F, A] def parseJson[F[_]: Sync, T]( className: String, r: org.http4s.Response[F] )(implicit decoder: io.circe.Decoder[T]): F[T] = r.attemptAs[T].value.flatMap { case Right(value) => Sync[F].pure(value) case Left(error) => Sync[F].raiseError(new io.grhodes.code.deploy.dashboard.v0.errors.FailedRequest(r.status.code, s"Invalid json for class[" + className + "]", None, error)) } } sealed trait Authorization extends _root_.scala.Product with _root_.scala.Serializable object Authorization { final case class Basic(username: String, password: Option[String] = None) extends Authorization } package interfaces { trait Client[F[_]] { def baseUrl: org.http4s.Uri def applications: io.grhodes.code.deploy.dashboard.v0.Applications[F] def info: io.grhodes.code.deploy.dashboard.v0.Info[F] } } trait Applications[F[_]] { def get( requestHeaders: Seq[(String, String)] = Nil ): F[Seq[io.grhodes.code.deploy.dashboard.v0.models.Application]] } trait Info[F[_]] { def get( requestHeaders: Seq[(String, String)] = Nil ): F[io.grhodes.code.deploy.dashboard.v0.models.Info] } package errors { final case class FailedRequest(responseCode: Int, message: String, requestUri: Option[_root_.java.net.URI] = None, parent: Exception = null) extends _root_.java.lang.Exception(s"HTTP $responseCode: $message", parent) } }