All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.profunktor.fs2rabbit.interpreter.ConnectionEffect.scala Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC3
Show newest version
/*
 * Copyright 2017-2019 ProfunKtor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dev.profunktor.fs2rabbit.interpreter

import cats.data.NonEmptyList
import cats.effect.{Resource, Sync}
import cats.implicits._
import dev.profunktor.fs2rabbit.algebra.Connection
import dev.profunktor.fs2rabbit.config.Fs2RabbitConfig
import dev.profunktor.fs2rabbit.effects.Log
import dev.profunktor.fs2rabbit.model.{AMQPChannel, AMQPConnection, RabbitChannel, RabbitConnection}
import com.rabbitmq.client.{Address, ConnectionFactory}
import javax.net.ssl.SSLContext

import scala.collection.JavaConverters._

class ConnectionEffect[F[_]: Log: Sync](
    factory: ConnectionFactory,
    addresses: NonEmptyList[Address]
) extends Connection[Resource[F, ?]] {

  private[fs2rabbit] def acquireChannel(connection: AMQPConnection): F[AMQPChannel] =
    Sync[F]
      .delay(connection.value.createChannel)
      .flatTap(c => Log[F].info(s"Acquired channel: $c"))
      .map(RabbitChannel)

  private[fs2rabbit] val acquireConnection: F[AMQPConnection] =
    Sync[F]
      .delay(factory.newConnection(addresses.toList.asJava))
      .flatTap(c => Log[F].info(s"Acquired connection: $c"))
      .map(RabbitConnection)

  override def createConnection: Resource[F, AMQPConnection] =
    Resource.make(acquireConnection) {
      case RabbitConnection(conn) =>
        Log[F].info(s"Releasing connection: $conn previously acquired.") *>
          Sync[F].delay { if (conn.isOpen) conn.close() }
    }

  override def createChannel(connection: AMQPConnection): Resource[F, AMQPChannel] =
    Resource.make(acquireChannel(connection)) {
      case RabbitChannel(channel) =>
        Sync[F].delay { if (channel.isOpen) channel.close() }
    }
}

object ConnectionEffect {

  private[fs2rabbit] def mkConnectionFactory[F[_]: Sync](
      config: Fs2RabbitConfig,
      sslContext: Option[SSLContext]
  ): F[(ConnectionFactory, NonEmptyList[Address])] =
    Sync[F].delay {
      val factory   = new ConnectionFactory()
      val firstNode = config.nodes.head
      factory.setHost(firstNode.host)
      factory.setPort(firstNode.port)
      factory.setVirtualHost(config.virtualHost)
      factory.setConnectionTimeout(config.connectionTimeout)
      factory.setAutomaticRecoveryEnabled(config.automaticRecovery)
      if (config.ssl) {
        sslContext.fold(factory.useSslProtocol())(factory.useSslProtocol)
      }
      config.username.foreach(factory.setUsername)
      config.password.foreach(factory.setPassword)
      val addresses = config.nodes.map(node => new Address(node.host, node.port))
      (factory, addresses)
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy