sec.api.grpc.convert.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2020 Scala EventStoreDB Client
*
* 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 sec
package api
package grpc
import cats.syntax.all.*
import io.grpc.{Metadata, Status, StatusRuntimeException}
import sec.api.exceptions.*
import sec.api.grpc.constants.Exceptions as ce
private[sec] object convert:
//======================================================================================================================
private[grpc] object keys:
val exception: Metadata.Key[String] = Metadata.Key.of(ce.ExceptionKey, StringMarshaller)
val streamName: Metadata.Key[String] = Metadata.Key.of(ce.StreamName, StringMarshaller)
val groupName: Metadata.Key[String] = Metadata.Key.of(ce.GroupName, StringMarshaller)
val reason: Metadata.Key[String] = Metadata.Key.of(ce.Reason, StringMarshaller)
val loginName: Metadata.Key[String] = Metadata.Key.of(ce.LoginName, StringMarshaller)
val expectedVersion: Metadata.Key[Long] = Metadata.Key.of(ce.ExpectedVersion, LongMarshaller)
val actualVersion: Metadata.Key[Long] = Metadata.Key.of(ce.ActualVersion, LongMarshaller)
val maximumAppendSize: Metadata.Key[Int] = Metadata.Key.of(ce.MaximumAppendSize, IntMarshaller)
val leaderEndpointHost: Metadata.Key[String] = Metadata.Key.of(ce.LeaderEndpointHost, StringMarshaller)
val leaderEndpointPort: Metadata.Key[Int] = Metadata.Key.of(ce.LeaderEndpointPort, IntMarshaller)
//======================================================================================================================
extension (md: Metadata)
private[grpc] def getOpt[T](key: Metadata.Key[T]): Option[T] =
Either.catchNonFatal(Option(md.get(key))).toOption.flatten
val convertToEs: StatusRuntimeException => Option[EsException] = ex =>
val unknown = ""
val md = ex.getTrailers
val exception = md.getOpt(keys.exception)
def streamName = md.getOpt(keys.streamName).getOrElse(unknown)
def groupName = md.getOpt(keys.groupName).getOrElse(unknown)
def reason = md.getOpt(keys.reason).getOrElse(unknown)
def expected = md.getOpt(keys.expectedVersion)
def actual = md.getOpt(keys.actualVersion)
def loginName = md.getOpt(keys.loginName).getOrElse(unknown)
def maximumAppendSize = md.getOpt(keys.maximumAppendSize)
def leaderEndpointHost = md.getOpt(keys.leaderEndpointHost)
def leaderEndpointPort = md.getOpt(keys.leaderEndpointPort)
val reified: Option[EsException] = exception.map {
case ce.AccessDenied => AccessDenied
case ce.InvalidTransaction => InvalidTransaction
case ce.StreamDeleted => StreamDeleted(streamName)
case ce.WrongExpectedVersion => WrongExpectedVersion(streamName, expected, actual)
case ce.StreamNotFound => StreamNotFound(streamName)
case ce.MaximumAppendSizeExceeded => MaximumAppendSizeExceeded(maximumAppendSize)
case ce.NotLeader => NotLeader(leaderEndpointHost, leaderEndpointPort)
case ce.PersistentSubscriptionFailed => PersistentSubscription.Failed(streamName, groupName, reason)
case ce.PersistentSubscriptionDoesNotExist => PersistentSubscription.NotFound(streamName, groupName)
case ce.PersistentSubscriptionExists => PersistentSubscription.Exists(streamName, groupName)
case ce.MaximumSubscribersReached => PersistentSubscription.MaximumSubscribersReached(streamName, groupName)
case ce.PersistentSubscriptionDropped => PersistentSubscription.Dropped(streamName, groupName)
case ce.UserNotFound => UserNotFound(loginName)
case unknown => UnknownError(s"Exception key: $unknown")
}
reified orElse serverUnavailable(ex) orElse resubscriptionRequired(ex)
val serverUnavailable: StatusRuntimeException => Option[ServerUnavailable] = ex =>
val cause = Option(ex.getCause()).fold("")(c => s", cause: ${c.getMessage}")
Option.when(ex.getStatus.getCode == Status.Code.UNAVAILABLE)(ServerUnavailable(s"${ex.getMessage}$cause"))
val resubscriptionRequired: StatusRuntimeException => Option[ResubscriptionRequired] = ex =>
val isAborted = ex.getStatus.getCode == Status.Code.ABORTED
val msg = Option(ex.getMessage).getOrElse("")
val isResubscription = msg.contains("resubscription required")
Option.when(isAborted && isResubscription)(ResubscriptionRequired(msg))
//======================================================================================================================
© 2015 - 2024 Weber Informatics LLC | Privacy Policy