Skip to content

Commit

Permalink
Migrate Expanded and CompactedJsonLd to Cats Effect
Browse files Browse the repository at this point in the history
  • Loading branch information
shinyhappydan committed Oct 18, 2023
1 parent 0db47dd commit b667f3e
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.model.ComponentDescription.ServiceDescr
import ch.epfl.bluebrain.nexus.delta.sdk.model.Name
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.testkit.blazegraph.BlazegraphDocker
import ch.epfl.bluebrain.nexus.testkit.ce.CatsIOValues
import ch.epfl.bluebrain.nexus.testkit.{EitherValuable, IOValues, TestHelpers, TestMatchers}
import io.circe.Json
import monix.execution.Scheduler
Expand All @@ -46,7 +47,8 @@ class BlazegraphClientSpec(docker: BlazegraphDocker)
with Eventually
with Inspectors
with TestMatchers
with IOValues {
with IOValues
with CatsIOValues {

implicit private val sc: Scheduler = Scheduler.global
implicit private val httpCfg: HttpClientConfig = httpClientConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ch.epfl.bluebrain.nexus.delta.plugins.compositeviews.model.CompositeViewP
import ch.epfl.bluebrain.nexus.delta.plugins.elasticsearch.client.ElasticSearchClient.Refresh
import ch.epfl.bluebrain.nexus.delta.plugins.elasticsearch.client.{ElasticSearchClient, IndexLabel}
import ch.epfl.bluebrain.nexus.delta.plugins.elasticsearch.indexing.{ElasticSearchSink, GraphResourceToDocument}
import ch.epfl.bluebrain.nexus.delta.rdf.RdfError
import ch.epfl.bluebrain.nexus.delta.rdf.graph.Graph
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdJavaApi}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.{ContextValue, RemoteContextResolution}
Expand All @@ -24,6 +25,7 @@ import ch.epfl.bluebrain.nexus.delta.sourcing.state.GraphResource
import ch.epfl.bluebrain.nexus.delta.sourcing.stream.Elem
import ch.epfl.bluebrain.nexus.delta.sourcing.stream.Elem.{DroppedElem, FailedElem, SuccessElem}
import ch.epfl.bluebrain.nexus.delta.sourcing.stream.Operation.Sink
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._
import fs2.Chunk
import monix.bio.Task
import shapeless.Typeable
Expand Down Expand Up @@ -124,7 +126,7 @@ final class Batch[SinkFormat](
fullGraph
.replaceRootNode(iri"${gr.id}/alias")
.toCompactedJsonLd(ContextValue.empty)
.flatMap(_.toGraph)
.flatMap(_.toGraph.toBIO[RdfError])
.map(g => gr.copy(graph = g.replaceRootNode(gr.id)))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.ExpandedJsonLd
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdJavaApi}
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.testkit.ce.CatsIOValues
import ch.epfl.bluebrain.nexus.testkit.{CirceEq, IOValues, TestHelpers}
import io.circe.syntax.EncoderOps
import monix.bio.UIO
Expand All @@ -18,6 +19,7 @@ class JsonLdDocumentSpec
with Matchers
with TestHelpers
with IOValues
with CatsIOValues
with OptionValues
with ContextFixtures
with CirceEq {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class SearchSparqlQuerySpec

private def toNTriples(json: Json): NTriples = {
for {
expanded <- toCatsIO(ExpandedJsonLd(json))
expanded <- ExpandedJsonLd(json)
graph <- IO.fromEither(expanded.toGraph)
ntriples <- IO.fromEither(graph.toNTriples)
} yield ntriples
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package ch.epfl.bluebrain.nexus.delta.rdf

import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.RemoteContext
import monix.bio.IO

/**
* Gives additional information besides the result of the Json-Ld operation
Expand All @@ -18,6 +18,6 @@ final case class ExplainResult[A](remoteContexts: Map[Iri, RemoteContext], value
def map[B](f: A => B): ExplainResult[B] =
copy(value = f(value))

def evalMap[E, B](f: A => IO[E, B]): IO[E, ExplainResult[B]] =
def evalMap[B](f: A => IO[B]): IO[ExplainResult[B]] =
f(value).map { b => copy(value = b) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,13 @@ final case class Graph private (rootNode: IriOrBNode, value: DatasetGraph) { sel
opts: JsonLdOptions
): IO[RdfError, CompactedJsonLd] = {

def computeCompacted(id: IriOrBNode, input: Json) = {
def computeCompacted(id: IriOrBNode, input: Json): IO[RdfError, CompactedJsonLd] = {
if (triples.isEmpty) UIO.delay(CompactedJsonLd.unsafe(id, contextValue, JsonObject.empty))
else if (value.listGraphNodes().asScala.nonEmpty) CompactedJsonLd(id, contextValue, input)
else CompactedJsonLd.frame(id, contextValue, input)
else if (value.listGraphNodes().asScala.nonEmpty) {
CompactedJsonLd(id, contextValue, input).toBIO[RdfError]
} else {
CompactedJsonLd.frame(id, contextValue, input).toBIO[RdfError]
}
}

if (rootNode.isBNode)
Expand All @@ -257,7 +260,7 @@ final case class Graph private (rootNode: IriOrBNode, value: DatasetGraph) { sel
resolution: RemoteContextResolution,
opts: JsonLdOptions
): IO[RdfError, ExpandedJsonLd] =
toCompactedJsonLd(ContextValue.empty).flatMap(_.toExpanded)
toCompactedJsonLd(ContextValue.empty).flatMap(_.toExpanded.toBIO[RdfError])

/**
* Merges the current graph with the passed ''that'' while keeping the current ''rootNode''
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package ch.epfl.bluebrain.nexus.delta.rdf.jsonld

import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.{BNode, Iri}
import ch.epfl.bluebrain.nexus.delta.rdf.graph.Graph
import ch.epfl.bluebrain.nexus.delta.rdf.implicits._
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdOptions}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context._
import ch.epfl.bluebrain.nexus.delta.rdf.{IriOrBNode, RdfError}
import io.circe.syntax._
import io.circe.{Decoder, DecodingFailure, Encoder, Json, JsonObject}
import monix.bio.IO
import io.circe._

/**
* Json-LD Compacted Document. CompactedJsonLd specific implementation is entity centric, having always only one root
Expand All @@ -29,7 +28,7 @@ final case class CompactedJsonLd private (rootId: IriOrBNode, ctx: ContextValue,
opts: JsonLdOptions,
api: JsonLdApi,
resolution: RemoteContextResolution
): IO[RdfError, ExpandedJsonLd] =
): IO[ExpandedJsonLd] =
ExpandedJsonLd(json).map(_.replaceId(rootId))

/**
Expand All @@ -39,7 +38,7 @@ final case class CompactedJsonLd private (rootId: IriOrBNode, ctx: ContextValue,
opts: JsonLdOptions,
api: JsonLdApi,
resolution: RemoteContextResolution
): IO[RdfError, Graph] =
): IO[Graph] =
toExpanded.flatMap(expanded => IO.fromEither(expanded.toGraph))

/**
Expand Down Expand Up @@ -95,13 +94,12 @@ object CompactedJsonLd {
rootId: IriOrBNode,
contextValue: ContextValue,
input: Json
)(implicit api: JsonLdApi, rcr: RemoteContextResolution, opts: JsonLdOptions): IO[RdfError, CompactedJsonLd] =
)(implicit api: JsonLdApi, rcr: RemoteContextResolution, opts: JsonLdOptions): IO[CompactedJsonLd] =
api
.compact(input, contextValue)
.map { compacted =>
CompactedJsonLd(rootId, contextValue, compacted.remove(keywords.context))
}
.toBIO[RdfError]

/**
* Creates a [[CompactedJsonLd]] document framed on the passed ''rootId''.
Expand All @@ -117,15 +115,14 @@ object CompactedJsonLd {
rootId: IriOrBNode,
contextValue: ContextValue,
input: Json
)(implicit api: JsonLdApi, rcr: RemoteContextResolution, opts: JsonLdOptions): IO[RdfError, CompactedJsonLd] =
)(implicit api: JsonLdApi, rcr: RemoteContextResolution, opts: JsonLdOptions): IO[CompactedJsonLd] =
rootId.asIri.map(iri => contextValue.contextObj deepMerge JsonObject(keywords.id -> iri.asJson)) match {
case Some(frame) =>
api
.frame(input, frame.asJson)
.map { compacted =>
CompactedJsonLd(rootId, contextValue, compacted.remove(keywords.context))
}
.toBIO[RdfError]
case _ => apply(rootId, contextValue, input)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch.epfl.bluebrain.nexus.delta.rdf.jsonld

import cats.effect.IO
import cats.implicits._
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.{BNode, Iri}
import ch.epfl.bluebrain.nexus.delta.rdf.RdfError.{InvalidIri, UnexpectedJsonLd}
Expand All @@ -15,7 +16,6 @@ import ch.epfl.bluebrain.nexus.delta.rdf.{ExplainResult, IriOrBNode, RdfError}
import ch.epfl.bluebrain.nexus.delta.rdf.syntax._
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Json, JsonObject}
import monix.bio.{IO, UIO}

import java.util.UUID

Expand All @@ -42,7 +42,7 @@ final case class ExpandedJsonLd private (rootId: IriOrBNode, obj: JsonObject) ex
opts: JsonLdOptions,
api: JsonLdApi,
resolution: RemoteContextResolution
): IO[RdfError, CompactedJsonLd] =
): IO[CompactedJsonLd] =
CompactedJsonLd(rootId, contextValue, json)

/**
Expand Down Expand Up @@ -185,14 +185,14 @@ object ExpandedJsonLd {
api: JsonLdApi,
resolution: RemoteContextResolution,
opts: JsonLdOptions
): IO[RdfError, ExpandedJsonLd] =
): IO[ExpandedJsonLd] =
explain(input).map(_.value)

def explain(input: Json)(implicit
api: JsonLdApi,
resolution: RemoteContextResolution,
opts: JsonLdOptions
): IO[RdfError, ExplainResult[ExpandedJsonLd]] =
): IO[ExplainResult[ExpandedJsonLd]] =
api
.explainExpand(input)
.flatMap {
Expand Down Expand Up @@ -244,9 +244,8 @@ object ExpandedJsonLd {
api
.expand(Json.obj(keywords.id -> graphId.asJson, keywords.graph -> expandedSeq.asJson))
.map(_ -> true)
.toBIO[RdfError]
else
UIO.pure((expandedSeq, false))
IO.pure((expandedSeq, false))
result <- IO.fromEither(expanded(expandedSeqFinal))

} yield (result, isGraph)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.{IriOrBNode, RdfError}
import io.circe.{Encoder, Json}
import io.circe.syntax._
import monix.bio.IO
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._

trait JsonLdEncoder[A] {

Expand Down Expand Up @@ -138,7 +139,7 @@ object JsonLdEncoder {
)(implicit opts: JsonLdOptions, api: JsonLdApi, rcr: RemoteContextResolution): IO[RdfError, CompactedJsonLd] =
for {
(expanded, context) <- expandAndExtractContext(value)
compacted <- expanded.toCompacted(context)
compacted <- expanded.toCompacted(context).toBIO[RdfError]
} yield compacted

override def expand(
Expand All @@ -152,6 +153,7 @@ object JsonLdEncoder {
val json = value.asJson
val context = contextFromJson(json)
ExpandedJsonLd(json.replaceContext(context.contextObj))
.toBIO[RdfError]
.map {
case expanded if fId(value).isBNode && expanded.rootId.isIri => expanded
case expanded => expanded.replaceId(fId(value))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdJavaApi}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.RemoteContextResolution
import ch.epfl.bluebrain.nexus.delta.rdf.syntax._
import ch.epfl.bluebrain.nexus.testkit.ce.CatsIOValues
import ch.epfl.bluebrain.nexus.testkit.{EitherValuable, IOValues, TestHelpers}
import org.scalatest.Inspectors
import org.scalatest.matchers.should.Matchers
Expand All @@ -17,6 +18,7 @@ class ShaclEngineSpec
with Matchers
with TestHelpers
with IOValues
with CatsIOValues
with EitherValuable
with Inspectors {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.ExpandedJsonLd
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdJavaApi}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.RemoteContextResolution
import ch.epfl.bluebrain.nexus.delta.rdf.syntax._
import ch.epfl.bluebrain.nexus.testkit.ce.CatsIOValues
import ch.epfl.bluebrain.nexus.testkit.{EitherValuable, IOValues, TestHelpers}
import io.circe.Json
import io.circe.syntax._
Expand All @@ -21,6 +22,7 @@ class ValidationReportSpec
with TestHelpers
with EitherValuable
with OptionValues
with CatsIOValues
with IOValues {

implicit val api: JsonLdApi = JsonLdJavaApi.strict
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package ch.epfl.bluebrain.nexus.delta.sdk.jsonld

import ch.epfl.bluebrain.nexus.delta.kernel.Mapper
import ch.epfl.bluebrain.nexus.delta.kernel.utils.UUIDF
import ch.epfl.bluebrain.nexus.delta.rdf.ExplainResult
import ch.epfl.bluebrain.nexus.delta.rdf.{ExplainResult, RdfError}
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.{BNode, Iri}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdOptions}
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.ContextValue.ContextObject
Expand All @@ -17,6 +17,7 @@ import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ProjectContext
import ch.epfl.bluebrain.nexus.delta.sdk.resolvers.ResolverContextResolution
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._
import io.circe.syntax._
import io.circe.{Json, JsonObject}
import monix.bio.{IO, UIO}
Expand All @@ -38,10 +39,11 @@ sealed abstract class JsonLdSourceProcessor(implicit api: JsonLdApi) {
implicit val opts: JsonLdOptions = JsonLdOptions(base = Some(context.base.iri))
ExpandedJsonLd
.explain(source)
.toBIO[RdfError]
.flatMap {
case result if result.value.isEmpty && source.topContextValueOrEmpty.isEmpty =>
val ctx = defaultCtx(context)
ExpandedJsonLd.explain(source.addContext(ctx.contextObj)).map(ctx -> _)
ExpandedJsonLd.explain(source.addContext(ctx.contextObj)).map(ctx -> _).toBIO[RdfError]
case result =>
UIO.pure(source.topContextValueOrEmpty -> result)
}
Expand Down Expand Up @@ -119,7 +121,7 @@ object JsonLdSourceProcessor {
originalExpanded = result.value
iri <- getOrGenerateId(originalExpanded.rootId.asIri, context)
expanded = originalExpanded.replaceId(iri)
compacted <- expanded.toCompacted(ctx).mapError(err => InvalidJsonLdFormat(Some(iri), err))
compacted <- expanded.toCompacted(ctx).toBIO[RdfError].mapError(err => InvalidJsonLdFormat(Some(iri), err))
} yield JsonLdResult(iri, compacted, expanded, result.remoteContexts)
}.mapError(rejectionMapper.to)

Expand All @@ -146,7 +148,7 @@ object JsonLdSourceProcessor {
(ctx, result) <- expandSource(context, source.addContext(contextIri: _*))
originalExpanded = result.value
expanded <- checkAndSetSameId(iri, originalExpanded)
compacted <- expanded.toCompacted(ctx).mapError(err => InvalidJsonLdFormat(Some(iri), err))
compacted <- expanded.toCompacted(ctx).toBIO[RdfError].mapError(err => InvalidJsonLdFormat(Some(iri), err))
} yield JsonLdResult(iri, compacted, expanded, result.remoteContexts)
}.mapError(rejectionMapper.to)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.epfl.bluebrain.nexus.delta.sdk.generators

import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary.schemas
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.ExpandedJsonLd
Expand All @@ -17,12 +16,12 @@ import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Subject}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ResourceRef.Latest
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{ProjectRef, ResourceRef}
import ch.epfl.bluebrain.nexus.testkit.IOValues
import ch.epfl.bluebrain.nexus.testkit.ce.CatsIOValues
import io.circe.Json

import java.time.Instant

object ResourceGen extends IOValues {
object ResourceGen extends CatsIOValues {

// We put a lenient api for schemas otherwise the api checks data types before the actual schema validation process
implicit val api: JsonLdApi = JsonLdJavaApi.strict
Expand Down Expand Up @@ -77,8 +76,8 @@ object ResourceGen extends IOValues {
tags: Tags = Tags.empty
)(implicit resolution: RemoteContextResolution): IO[Resource] = {
for {
expanded <- ExpandedJsonLd(source).toCatsIO.map(_.replaceId(id))
compacted <- expanded.toCompacted(source.topContextValueOrEmpty).toCatsIO
expanded <- ExpandedJsonLd(source).map(_.replaceId(id))
compacted <- expanded.toCompacted(source.topContextValueOrEmpty)
} yield {
Resource(id, project, tags, schema, source, compacted, expanded)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package ch.epfl.bluebrain.nexus.delta.sdk.generators

import cats.data.NonEmptyList
import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.kernel.effect.migration._
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.ExpandedJsonLd
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.api.{JsonLdApi, JsonLdJavaApi}
Expand Down Expand Up @@ -61,8 +60,8 @@ object SchemaGen extends CatsIOValues with EitherValuable {
tags: Tags = Tags.empty
)(implicit resolution: RemoteContextResolution): IO[Schema] = {
for {
expanded <- ExpandedJsonLd(source).toCatsIO.map(_.replaceId(id))
compacted <- expanded.toCompacted(source.topContextValueOrEmpty).toCatsIO
expanded <- ExpandedJsonLd(source).map(_.replaceId(id))
compacted <- expanded.toCompacted(source.topContextValueOrEmpty)
} yield {
Schema(id, project, tags, source, compacted, NonEmptyList.of(expanded))
}
Expand Down
Loading

0 comments on commit b667f3e

Please sign in to comment.