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

uk.gov.nationalarchives.dp.client.WorkflowClient.scala Maven / Gradle / Ivy

The newest version!
package uk.gov.nationalarchives.dp.client

import cats.MonadError
import cats.effect.Async
import cats.implicits.*
import sttp.client3.*
import sttp.model.Method
import uk.gov.nationalarchives.dp.client.Client.*
import uk.gov.nationalarchives.dp.client.WorkflowClient.StartWorkflowRequest

/** A client to start a Preservica workflow
  * @tparam F
  *   Type of the effect
  */
trait WorkflowClient[F[_]] {

  /** Starts a preservica workflow
    * @param startWorkflowRequest
    *   An instance of [[WorkflowClient.StartWorkflowRequest]] It contains details used to start the workflow
    * @return
    *   The id of the new workflow wrapped in the F effect.
    */
  def startWorkflow(startWorkflowRequest: StartWorkflowRequest): F[Int]
}

/** An object containing a method which returns an implementation of the WorkflowClient trait
  */
object WorkflowClient {

  /** Creates a new `WorkflowClient` instance.
    * @param clientConfig
    *   Configuration parameters needed to create the client
    * @param me
    *   An implicit instance of cats.MonadError
    * @param sync
    *   An implicit instance of cats.Sync
    * @tparam F
    *   The type of the effect
    * @tparam S
    *   The type of the Stream to be used for the streaming methods.
    * @return
    *   A new `WorkflowClient`
    */
  def createWorkflowClient[F[_], S](clientConfig: ClientConfig[F, S])(using
      me: MonadError[F, Throwable],
      sync: Async[F]
  ): WorkflowClient[F] = new WorkflowClient[F] {
    private val apiBaseUrl: String = clientConfig.apiBaseUrl
    private val client: Client[F, S] = Client(clientConfig)

    import client.*

    override def startWorkflow(startWorkflowRequest: StartWorkflowRequest): F[Int] = {
      val startWorkflowUrl = uri"$apiBaseUrl/sdb/rest/workflow/instances"
      val newLine = Some("\n  ")

      val workflowContextIdNode = startWorkflowRequest.workflowContextId
        .map { workflowId =>
          {workflowId}
        }

      val workflowContextNameNode = startWorkflowRequest.workflowContextName
        .map { workflowName =>
          {workflowName}
        }

      val parameterNodes = startWorkflowRequest.parameters.zipWithIndex
        .flatMap { case (parameter, index) =>
          List(
            List(if (index == 0) "" else "\n  "),
            
          {parameter.key}
          {parameter.value}
        
          )
        }

      val correlationIdNode =
        startWorkflowRequest.correlationId
          .map { correlationId =>
            {correlationId}
          }

      val requestNodes =
        List(
          workflowContextIdNode,
          newLine,
          workflowContextNameNode,
          newLine,
          correlationIdNode,
          newLine
        ).flatten ++ parameterNodes

      val xmlRequestBody =
        
          {
          requestNodes.map { requestNode =>
            requestNode
          }
        }
        

      val requestBodyString = s"\n$xmlRequestBody"
      for {
        _ <-
          if (startWorkflowRequest.workflowContextName.isEmpty && startWorkflowRequest.workflowContextId.isEmpty) {
            me.raiseError(
              PreservicaClientException(
                "You must pass in either a workflowContextName or a workflowContextId!"
              )
            )
          } else me.unit
        token <- getAuthenticationToken
        startWorkflowResponse <- sendXMLApiRequest(
          startWorkflowUrl.toString,
          token,
          Method.POST,
          Some(requestBodyString)
        )
        id <- dataProcessor.childNodeFromWorkflowInstance(startWorkflowResponse, "Id")
      } yield id.toInt
    }
  }

  /** A workflow request parameter
    * @param key
    *   The parameter key
    * @param value
    *   The parameter value
    */
  case class Parameter(key: String, value: String)

  /** A workflow request
    * @param workflowContextName
    *   An optional workflow context name. Either this or the context id must be provided
    * @param workflowContextId
    *   An optional workflow context id. Either this or the context name must be provided.
    * @param parameters
    *   An list of parameters. This can be empty
    * @param correlationId
    *   An optional correlation id. This can be empty.
    */
  case class StartWorkflowRequest(
      workflowContextName: Option[String] = None,
      workflowContextId: Option[Int] = None,
      parameters: List[Parameter] = Nil,
      correlationId: Option[String] = None
  )
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy