Skip to content

Commit

Permalink
Pass configuration for metadata back to client
Browse files Browse the repository at this point in the history
Provide calling client with configuration for metadata for the transfer

Configuration driven by the relevant schema
  • Loading branch information
TomJKing committed Aug 13, 2024
1 parent 5de4cd0 commit a6f68fb
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 9 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ lazy val root = (project in file("."))
keycloakMock % Test,
logbackClassic,
logBackEncoder,
metadataSchema,
mockito % Test,
pekkoTestKitHttp % Test,
pureConfig,
Expand Down
1 change: 1 addition & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ object Dependencies {
lazy val logBackEncoder = "net.logstash.logback" % "logstash-logback-encoder" % "7.4"
lazy val logbackClassic = "ch.qos.logback" % "logback-classic" % "1.5.6"

lazy val metadataSchema = "uk.gov.nationalarchives" % "da-metadata-schema_3" % "0.0.26"
lazy val mockito = "org.mockito" %% "mockito-scala" % mockitoVersion
lazy val mockitoScalaTest = "org.mockito" %% "mockito-scala-scalatest" % mockitoVersion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ sealed trait LoadDestinationModel
sealed trait MetadataPropertyModel

object LoadModel {
case class CustomMetadataConfiguration(required: Boolean = false) extends MetadataPropertyModel
case class MetadataPropertyDetails(propertyName: String, required: Boolean) extends MetadataPropertyModel
case class TransferConfiguration(
metadataPropertyDetails: Set[MetadataPropertyDetails] = Set(),
customMetadataConfiguration: CustomMetadataConfiguration = CustomMetadataConfiguration()
)
case class AWSS3LoadDestination(bucketName: String, bucketKeyPrefix: String) extends LoadDestinationModel
case class LoadDetails(
transferId: UUID,
recordsLoadDestination: AWSS3LoadDestination,
metadataLoadDestination: AWSS3LoadDestination,
metadataProperties: List[MetadataPropertyDetails] = List()
transferConfiguration: TransferConfiguration = TransferConfiguration()
) extends LoadModel
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package uk.gov.nationalarchives.tdr.transfer.service.services.dataload
import cats.effect.IO
import uk.gov.nationalarchives.tdr.keycloak.Token
import uk.gov.nationalarchives.tdr.transfer.service.ApplicationConfig
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{AWSS3LoadDestination, LoadDetails}
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{AWSS3LoadDestination, LoadDetails, TransferConfiguration}
import uk.gov.nationalarchives.tdr.transfer.service.services.GraphQlApiService
import uk.gov.nationalarchives.tdr.transfer.service.services.dataload.DataLoadInitiation.s3Config
import uk.gov.nationalarchives.tdr.transfer.service.services.schema.MetadataConfiguration

import java.util.UUID

Expand All @@ -22,7 +23,9 @@ class DataLoadInitiation(graphQlApiService: GraphQlApiService) {
private def loadDetails(transferId: UUID, userId: UUID): IO[LoadDetails] = {
val recordsS3Bucket = AWSS3LoadDestination(s"${s3Config.recordsUploadBucket}", s"$userId/$transferId")
val metadataS3Bucket = AWSS3LoadDestination(s"${s3Config.metadataUploadBucket}", s"$transferId/dataload")
IO(LoadDetails(transferId, recordsLoadDestination = recordsS3Bucket, metadataLoadDestination = metadataS3Bucket))
val metadataProperties = MetadataConfiguration.metadataConfiguration()
val transferConfiguration = TransferConfiguration(metadataProperties)
IO(LoadDetails(transferId, recordsLoadDestination = recordsS3Bucket, metadataLoadDestination = metadataS3Bucket, transferConfiguration))
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package uk.gov.nationalarchives.tdr.transfer.service.services.schema

import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.MetadataPropertyDetails

import scala.jdk.CollectionConverters._

object MetadataConfiguration {
def metadataConfiguration(): Set[MetadataPropertyDetails] = {
val schema = SchemaHandler.schema().get("allOf")
val properties = schema.get(0).get("properties").properties().asScala
val requiredProperties = schema.get(0).get("required").asScala.map(_.asText()).toSet
properties
.map(p => {
MetadataPropertyDetails(p.getKey, requiredProperties.contains(p.getKey))
})
.toSet
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package uk.gov.nationalarchives.tdr.transfer.service.services.schema

import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}

import java.io.InputStream

object SchemaHandler {
private def getJsonNodeFromStreamContent(content: InputStream): JsonNode = {
val mapper = new ObjectMapper()
mapper.readTree(content)
}

def schema(schemaLocation: String = "/metadata-schema/dataLoadSharePointSchema.schema.json"): JsonNode = {
getJsonNodeFromStreamContent(getClass.getResourceAsStream(schemaLocation))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@ import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend}
import uk.gov.nationalarchives.tdr.keycloak.TdrKeycloakDeployment
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{MetadataPropertyDetails, TransferConfiguration}

import scala.concurrent.ExecutionContextExecutor

trait BaseSpec extends AnyFlatSpec with MockitoSugar with Matchers with EitherValues {
implicit val executionContext: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
implicit val backend: SttpBackend[Identity, Any] = HttpURLConnectionBackend()
implicit val tdrKeycloakDeployment: TdrKeycloakDeployment = TdrKeycloakDeployment("authUrl", "realm", 60)

val expectedMetadataPropertyDetails: Set[MetadataPropertyDetails] = Set(
MetadataPropertyDetails("SHA256ClientSideChecksum", true),
MetadataPropertyDetails("ClientSideFileSize", true),
MetadataPropertyDetails("ClientSideFileLastModifiedDate", true),
MetadataPropertyDetails("ClientSideOriginalFilepath", true),
MetadataPropertyDetails("UUID", true)
)

val expectedTransferConfiguration: TransferConfiguration = TransferConfiguration(expectedMetadataPropertyDetails)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.scalatest.matchers.should.Matchers
import org.typelevel.ci.CIString
import uk.gov.nationalarchives.tdr.transfer.service.TestUtils.{invalidToken, userId, validUserToken}
import uk.gov.nationalarchives.tdr.transfer.service.api.controllers.LoadController
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.MetadataPropertyDetails
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{MetadataPropertyDetails, TransferConfiguration}
import uk.gov.nationalarchives.tdr.transfer.service.services.ExternalServicesSpec

class TransferServiceServerSpec extends ExternalServicesSpec with Matchers {
Expand Down Expand Up @@ -55,13 +55,11 @@ class TransferServiceServerSpec extends ExternalServicesSpec with Matchers {
"bucketKeyPrefix" := s"$transferId/dataload"
)

val metadataProperties: List[MetadataPropertyDetails] = List()

val expectedResponse = Json.obj(
"transferId" := transferId,
"recordsLoadDestination" := recordsDestination,
"metadataLoadDestination" := metadataLoadDestination,
"metadataProperties" := metadataProperties
"transferConfiguration" := expectedTransferConfiguration
)

response.status shouldBe Status.Ok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.nimbusds.oauth2.sdk.token.BearerAccessToken
import graphql.codegen.AddConsignment.addConsignment.AddConsignment
import uk.gov.nationalarchives.tdr.keycloak.Token
import uk.gov.nationalarchives.tdr.transfer.service.BaseSpec
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{AWSS3LoadDestination, LoadDetails}
import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{AWSS3LoadDestination, LoadDetails, TransferConfiguration}
import uk.gov.nationalarchives.tdr.transfer.service.services.GraphQlApiService

import java.util.UUID
Expand All @@ -31,7 +31,7 @@ class DataLoadInitiationSpec extends BaseSpec {
consignmentId,
AWSS3LoadDestination("s3BucketNameRecords", s"$userId/$consignmentId"),
AWSS3LoadDestination("s3BucketNameMetadata", s"$consignmentId/dataload"),
List()
expectedTransferConfiguration
)

val service = new DataLoadInitiation(mockGraphQlApiService)
Expand Down

0 comments on commit a6f68fb

Please sign in to comment.