diff --git a/docs/05-internals/design/api-v2/json-ld.md b/docs/05-internals/design/api-v2/json-ld.md index 3a91913fd0..2fa2d67500 100644 --- a/docs/05-internals/design/api-v2/json-ld.md +++ b/docs/05-internals/design/api-v2/json-ld.md @@ -22,7 +22,7 @@ License along with Knora. If not, see . ## JsonLDUtil Knora provides a utility object called `JsonLDUtil`, which wraps the -[JSON-LD Java API](https://github.com/jsonld-java/jsonld-java), and parses JSON-LD text to a +[titanium-json-ld Java library](https://github.com/filip26/titanium-json-ld), and parses JSON-LD text to a Knora data structure called `JsonLDDocument`. These classes provide commonly needed functionality for extracting and validating data from JSON-LD documents, as well as for constructing new documents. diff --git a/third_party/dependencies.bzl b/third_party/dependencies.bzl index 740f989876..f997db9255 100644 --- a/third_party/dependencies.bzl +++ b/third_party/dependencies.bzl @@ -97,8 +97,9 @@ def dependencies(): "de.heikoseeberger:akka-http-circe_2.12:1.21.0", "com.fasterxml.jackson.module:jackson-module-scala_2.12:2.9.4", - "com.github.jsonld-java:jsonld-java:0.12.0", - "com.apicatalog:titanium-json-ld:0.8.3", + "com.apicatalog:titanium-json-ld:0.8.5", + "javax.json:javax.json-api:1.1.4", + "org.glassfish:jakarta.json:1.1.6", # swagger (api documentation) "com.github.swagger-akka-http:swagger-akka-http_2.12:0.14.0", @@ -182,8 +183,8 @@ BASE_TEST_DEPENDENCIES_WITH_JSON = BASE_TEST_DEPENDENCIES + [ ] BASE_TEST_DEPENDENCIES_WITH_JSON_LD = BASE_TEST_DEPENDENCIES + [ - "@maven//:com_fasterxml_jackson_core_jackson_core", - "@maven//:com_github_jsonld_java_jsonld_java", + "@maven//:io_spray_spray_json_2_12", "@maven//:com_apicatalog_titanium_json_ld", + "@maven//:javax_json_javax_json_api", + "@maven//:org_glassfish_jakarta_json" ] - diff --git a/webapi/BUILD.bazel b/webapi/BUILD.bazel index 81d1ec9379..9f663c7671 100644 --- a/webapi/BUILD.bazel +++ b/webapi/BUILD.bazel @@ -60,11 +60,11 @@ scala_library( # "@maven//:ch_megard_akka_http_cors_2_12", "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_core", "@maven//:com_fasterxml_jackson_core_jackson_databind", "@maven//:com_github_andrewoma_dexx_collection", - "@maven//:com_github_jsonld_java_jsonld_java", "@maven//:com_apicatalog_titanium_json_ld", + "@maven//:javax_json_javax_json_api", + "@maven//:org_glassfish_jakarta_json", "@maven//:com_github_swagger_akka_http_swagger_akka_http_2_12", "@maven//:com_google_gwt_gwt_servlet", "@maven//:com_ibm_icu_icu4j", @@ -168,7 +168,6 @@ scala_library( # Test Libs "@maven//:com_typesafe_akka_akka_testkit_2_12", "@maven//:com_typesafe_akka_akka_http_testkit_2_12", - "@maven//:com_github_jsonld_java_jsonld_java", "@maven//:com_jsuereth_scala_arm_2_12", "@maven//:com_typesafe_akka_akka_actor_2_12", "@maven//:com_typesafe_akka_akka_http_2_12", diff --git a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel index 38c527dffd..c57a951f9a 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel +++ b/webapi/src/main/scala/org/knora/webapi/messages/BUILD.bazel @@ -13,8 +13,6 @@ scala_library( "//webapi/src/main/scala/org/knora/webapi/settings", "//webapi/src/main/scala/org/knora/webapi/util", "//webapi/src/main/scala/org/knora/webapi/util/cache", - "@maven//:com_fasterxml_jackson_core_jackson_core", - "@maven//:com_github_jsonld_java_jsonld_java", "@maven//:com_google_gwt_gwt_servlet", "@maven//:com_ibm_icu_icu4j", "@maven//:com_sksamuel_diff_diff", @@ -22,6 +20,9 @@ scala_library( "@maven//:com_typesafe_akka_akka_http_2_12", "@maven//:com_typesafe_akka_akka_http_core_2_12", "@maven//:com_typesafe_akka_akka_http_spray_json_2_12", + "@maven//:com_apicatalog_titanium_json_ld", + "@maven//:javax_json_javax_json_api", + "@maven//:org_glassfish_jakarta_json", "@maven//:com_typesafe_akka_akka_stream_2_12", "@maven//:com_typesafe_play_twirl_api_2_12", "@maven//:com_typesafe_scala_logging_scala_logging_2_12", diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/JsonLDUtil.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/JsonLDUtil.scala index 4c93020533..e2532353fd 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/JsonLDUtil.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/JsonLDUtil.scala @@ -19,17 +19,29 @@ package org.knora.webapi.messages.util +import java.io.{StringReader, StringWriter} +import java.util import java.util.UUID -import com.github.jsonldjava.core.{JsonLdOptions, JsonLdProcessor} -import com.github.jsonldjava.utils.JsonUtils +import com.apicatalog.jsonld._ +import com.apicatalog.jsonld.document._ +import javax.json._ +import javax.json.stream.JsonGenerator import org.knora.webapi._ import org.knora.webapi.exceptions.{BadRequestException, InconsistentTriplestoreDataException} import org.knora.webapi.messages.IriConversions._ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import org.knora.webapi.messages.{OntologyConstants, SmartIri, StringFormatter} -import org.knora.webapi.util.JavaUtil +/* + +The classes in this file provide a Scala API for formatting and parsing JSON-LD. The implementation +uses the javax.json API and a Java implementation of the JSON-LD API +(currently ). This shields the rest of Knora from the details +of the JSON-LD implementation. These classes also provide Knora-specific JSON-LD functionality to facilitate +reading data from Knora API requests and constructing Knora API responses. + +*/ /** * Constant strings used in JSON-LD. @@ -53,10 +65,9 @@ object JsonLDConstants { */ sealed trait JsonLDValue extends Ordered[JsonLDValue] { /** - * Converts this JSON-LD value to a Scala object that can be passed to [[org.knora.webapi.util.JavaUtil.deepScalaToJava]], - * whose return value can then be passed to the JSON-LD Java library. + * Converts this JSON-LD value to a `javax.json` [[JsonValue]]. */ - def toAny: Any + def toJavaxJsonValue: JsonValue } /** @@ -65,7 +76,9 @@ sealed trait JsonLDValue extends Ordered[JsonLDValue] { * @param value the underlying string. */ case class JsonLDString(value: String) extends JsonLDValue { - override def toAny: Any = value + override def toJavaxJsonValue: JsonString = { + Json.createValue(value) + } override def compare(that: JsonLDValue): Int = { that match { @@ -81,7 +94,9 @@ case class JsonLDString(value: String) extends JsonLDValue { * @param value the underlying integer. */ case class JsonLDInt(value: Int) extends JsonLDValue { - override def toAny: Any = value + override def toJavaxJsonValue: JsonNumber = { + Json.createValue(value) + } override def compare(that: JsonLDValue): Int = { that match { @@ -97,7 +112,13 @@ case class JsonLDInt(value: Int) extends JsonLDValue { * @param value the underlying boolean value. */ case class JsonLDBoolean(value: Boolean) extends JsonLDValue { - override def toAny: Any = value + override def toJavaxJsonValue: JsonValue = { + if (value) { + JsonValue.TRUE + } else { + JsonValue.FALSE + } + } override def compare(that: JsonLDValue): Int = { that match { @@ -113,8 +134,14 @@ case class JsonLDBoolean(value: Boolean) extends JsonLDValue { * @param value a map of keys to JSON-LD values. */ case class JsonLDObject(value: Map[String, JsonLDValue]) extends JsonLDValue { - override def toAny: Map[String, Any] = value.map { - case (k, v) => (k, v.toAny) + override def toJavaxJsonValue: JsonObject = { + val builder = Json.createObjectBuilder() + + for ((entryKey, entryValue) <- value) { + builder.add(entryKey, entryValue.toJavaxJsonValue) + } + + builder.build } /** @@ -530,7 +557,15 @@ case class JsonLDObject(value: Map[String, JsonLDValue]) extends JsonLDValue { case class JsonLDArray(value: Seq[JsonLDValue]) extends JsonLDValue { implicit private val stringFormatter: StringFormatter = StringFormatter.getGeneralInstance - override def toAny: Seq[Any] = value.map(_.toAny) + override def toJavaxJsonValue: JsonArray = { + val builder = Json.createArrayBuilder() + + for (elem <- value) { + builder.add(elem.toJavaxJsonValue) + } + + builder.build + } /** * Tries to interpret the elements of this array as JSON-LD objects containing `@language` and `@value`, @@ -681,21 +716,39 @@ case class JsonLDDocument(body: JsonLDObject, context: JsonLDObject = JsonLDObje def maybeUUID(key: String): Option[UUID] = body.maybeUUID(key: String) /** - * Converts this JSON-LD object to its compacted Java representation. + * Converts this JSON-LD document to its compacted representation. + */ + private def makeCompactedJavaxJsonObject: JsonObject = { + val bodyAsTitaniumJsonDocument: JsonDocument = JsonDocument.of(body.toJavaxJsonValue) + val contextAsTitaniumJsonDocument: JsonDocument = JsonDocument.of(context.toJavaxJsonValue) + JsonLd.compact(bodyAsTitaniumJsonDocument, contextAsTitaniumJsonDocument).get + } + + /** + * Formats this JSON-LD document as a string, using the specified [[JsonWriterFactory]]. + * + * @param jsonWriterFactory a [[JsonWriterFactory]] configured with the desired options. + * @return the formatted document. */ - private def makeCompactedObject: java.util.Map[IRI, AnyRef] = { - val contextAsJava = JavaUtil.deepScalaToJava(context.toAny) - val jsonAsJava = JavaUtil.deepScalaToJava(body.toAny) - JsonLdProcessor.compact(jsonAsJava, contextAsJava, new JsonLdOptions()) + private def formatWithJsonWriterFactory(jsonWriterFactory: JsonWriterFactory): String = { + val compactedJavaxJsonObject: JsonObject = makeCompactedJavaxJsonObject + val stringWriter = new StringWriter() + val jsonWriter = jsonWriterFactory.createWriter(stringWriter) + jsonWriter.write(compactedJavaxJsonObject) + jsonWriter.close() + stringWriter.toString } /** - * Converts this [[JsonLDDocument]] to a pretty-printed JSON-LD string. + * Converts this JSON-LD document to a pretty-printed JSON-LD string. * * @return the formatted document. */ def toPrettyString: String = { - JsonUtils.toPrettyString(makeCompactedObject) + val config = new util.HashMap[String, Boolean]() + config.put(JsonGenerator.PRETTY_PRINTING, true) + val jsonWriterFactory: JsonWriterFactory = Json.createWriterFactory(config) + formatWithJsonWriterFactory(jsonWriterFactory) } /** @@ -704,7 +757,9 @@ case class JsonLDDocument(body: JsonLDObject, context: JsonLDObject = JsonLDObje * @return the formatted document. */ def toCompactString: String = { - JsonUtils.toString(makeCompactedObject) + val config = new util.HashMap[String, Boolean]() + val jsonWriterFactory: JsonWriterFactory = Json.createWriterFactory(config) + formatWithJsonWriterFactory(jsonWriterFactory) } } @@ -845,56 +900,59 @@ object JsonLDUtil { * @return a [[JsonLDDocument]]. */ def parseJsonLD(jsonLDString: String): JsonLDDocument = { - val jsonObject: AnyRef = try { - JsonUtils.fromString(jsonLDString) - } catch { - case e: com.fasterxml.jackson.core.JsonParseException => throw BadRequestException(s"Couldn't parse JSON-LD: ${e.getMessage}") - } + // Parse the string into a javax.json.JsonStructure. + val stringReader = new StringReader(jsonLDString) + val jsonReader: JsonReader = Json.createReader(stringReader) + val jsonStructure: JsonStructure = jsonReader.read() - val context: java.util.HashMap[String, Any] = new java.util.HashMap[String, Any]() - val options: JsonLdOptions = new JsonLdOptions() - val compact: java.util.Map[IRI, AnyRef] = JsonLdProcessor.compact(jsonObject, context, options) - val scalaColl: Any = JavaUtil.deepJavaToScala(compact) + // Convert the JsonStructure to a Titanium JsonDocument. + val titaniumDocument: JsonDocument = JsonDocument.of(jsonStructure) - val scalaMap: Map[String, Any] = try { - scalaColl.asInstanceOf[Map[String, Any]] - } catch { - case _: java.lang.ClassCastException => throw BadRequestException(s"Expected JSON-LD object: $scalaColl") - } + // Use Titanium to compact the document with an empty context. + val emptyContext = JsonDocument.of(Json.createObjectBuilder().build()) + val compactedJsonObject: JsonObject = JsonLd.compact(titaniumDocument, emptyContext).get - mapToJsonLDDocument(scalaMap) + // Convert the resulting javax.json.JsonObject to a JsonLDDocument. + javaxJsonObjectToJsonLDDocument(compactedJsonObject) } /** - * Converts a map into a [[JsonLDDocument]]. + * Converts JSON object into a [[JsonLDDocument]]. * - * @param docContent a map representing a JSON-LD object. + * @param jsonObject a JSON object. * @return */ - private def mapToJsonLDDocument(docContent: Map[String, Any]): JsonLDDocument = { - def anyToJsonLDValue(anyVal: Any): JsonLDValue = { - anyVal match { - case string: String => JsonLDString(string) - case int: Int => JsonLDInt(int) - case bool: Boolean => JsonLDBoolean(bool) - - case obj: Map[_, _] => - val content: Map[String, JsonLDValue] = obj.map { - case (key: String, value: Any) => key -> anyToJsonLDValue(value) - case (otherKey, otherValue) => throw BadRequestException(s"Unexpected types in JSON-LD object: $otherKey, $otherValue") - } + private def javaxJsonObjectToJsonLDDocument(jsonObject: JsonObject): JsonLDDocument = { + import collection.JavaConverters._ + + def jsonValueToJsonLDValue(jsonValue: JsonValue): JsonLDValue = { + jsonValue match { + case jsonString: JsonString => JsonLDString(jsonString.getString) + case jsonNumber: JsonNumber => JsonLDInt(jsonNumber.intValue) + case JsonValue.TRUE => JsonLDBoolean(true) + case JsonValue.FALSE => JsonLDBoolean(false) + + case jsonObject: JsonObject => + val content: Map[IRI, JsonLDValue] = jsonObject.keySet.asScala.toSet.map { + key: IRI => key -> jsonValueToJsonLDValue(jsonObject.get(key)) + }.toMap JsonLDObject(content) - case array: Seq[Any] => JsonLDArray(array.map(value => anyToJsonLDValue(value))) + case jsonArray: JsonArray => + val content: Seq[JsonLDValue] = jsonArray.asScala.map { + elem => jsonValueToJsonLDValue(elem) + } + + JsonLDArray(content) - case _ => throw BadRequestException(s"Unexpected type in JSON-LD input: $anyVal") + case _ => throw BadRequestException(s"Unexpected type in JSON-LD input: $jsonValue") } } - anyToJsonLDValue(docContent) match { + jsonValueToJsonLDValue(jsonObject) match { case obj: JsonLDObject => JsonLDDocument(body = obj, context = JsonLDObject(Map.empty[IRI, JsonLDValue])) - case _ => throw BadRequestException(s"Expected JSON-LD object: $docContent") + case _ => throw BadRequestException(s"Expected JSON-LD object: $jsonObject") } } } diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/standoffmessages/StandoffMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/standoffmessages/StandoffMessagesV2.scala index 9bf9085307..d7ba6358ec 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/standoffmessages/StandoffMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/standoffmessages/StandoffMessagesV2.scala @@ -199,7 +199,7 @@ case class CreateMappingResponseV2(mappingIri: IRI, label: String, projectIri: S val body = JsonLDObject(Map( JsonLDConstants.ID -> JsonLDString(mappingIri), JsonLDConstants.TYPE -> JsonLDString(OntologyConstants.KnoraBase.XMLToStandoffMapping.toSmartIri.toOntologySchema(targetSchema).toString), - "rdfs:label" -> JsonLDString(label), + OntologyConstants.Rdfs.Label -> JsonLDString(label), OntologyConstants.KnoraApiV2Complex.AttachedToProject.toSmartIri.toOntologySchema(targetSchema).toString -> JsonLDUtil.iriToJsonLDObject(projectIri.toString) )) diff --git a/webapi/src/main/scala/org/knora/webapi/util/JavaUtil.scala b/webapi/src/main/scala/org/knora/webapi/util/JavaUtil.scala index e139f6d229..7d9b9963bc 100644 --- a/webapi/src/main/scala/org/knora/webapi/util/JavaUtil.scala +++ b/webapi/src/main/scala/org/knora/webapi/util/JavaUtil.scala @@ -46,43 +46,6 @@ object JavaUtil { def biFunction[A, B, C](f: (A, B) => C): BiFunction[A, B, C] = (a: A, b: B) => f(a, b) - /** - * Recursively converts a Java collection into a Scala collection. - * - * Usage: `val scalaObj = deepScalaToJava(javaObj).asInstanceOf[Map[String, Any]]` - * - * @param javaObj the Java collection to be converted. - * @return an equivalent Scala collection. - */ - def deepJavaToScala(javaObj: Any): Any = { - import collection.JavaConverters._ - javaObj match { - case x: java.util.HashMap[_, _] => x.asScala.toMap.mapValues(deepJavaToScala) - case x: java.util.ArrayList[_] => x.asScala.toList.map(deepJavaToScala) - case _ => javaObj - } - } - - /** - * Recursively converts a Scala collection into a Java collection. - * - * @param scalaCollection the Scala collection to be converted. - * @return an equivalent Java collection. - */ - def deepScalaToJava(scalaCollection: Any): Any = { - import collection.JavaConverters._ - - scalaCollection match { - case x: List[_] => x.map(deepScalaToJava).asJava - case x: Seq[_] => x.map(deepScalaToJava).asJava - case x: Array[_] => x.map(deepScalaToJava) - case x: collection.mutable.Map[_, _] => x.mapValues(deepScalaToJava).asJava - case x: collection.immutable.Map[_, _] => x.mapValues(deepScalaToJava).asJava - case x: collection.Map[_, _] => x.mapValues(deepScalaToJava).asJava - case _ => scalaCollection - } - } - /** * Helps turn matches for optional regular expression groups, which can be null, into Scala Option objects. See * [[https://stackoverflow.com/a/18794646]]. diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/JSONLDHandlingV2R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/JSONLDHandlingV2R2RSpec.scala index 90b8915584..f2c4ca3bd8 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/JSONLDHandlingV2R2RSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/JSONLDHandlingV2R2RSpec.scala @@ -25,13 +25,12 @@ import java.net.URLEncoder import akka.actor.ActorSystem import akka.http.javadsl.model.StatusCodes import akka.http.scaladsl.testkit.RouteTestTimeout -import com.github.jsonldjava.utils.JsonUtils import org.knora.webapi._ import org.knora.webapi.e2e.v2.ResponseCheckerV2._ import org.knora.webapi.messages.store.triplestoremessages.RdfDataObject import org.knora.webapi.messages.util.JsonLDUtil import org.knora.webapi.routing.v2.ResourcesRouteV2 -import org.knora.webapi.util.{FileUtil, JavaUtil} +import spray.json._ import scala.concurrent.ExecutionContextExecutor @@ -58,14 +57,14 @@ class JSONLDHandlingV2R2RSpec extends R2RSpec { RdfDataObject(path = "test_data/all_data/incunabula-data.ttl", name = "http://www.knora.org/data/0803/incunabula") ) - "The JSONLD processor" should { + "The JSON-LD processor" should { "expand prefixes (on the client side)" in { - // JSONLD with prefixes and context object + // JSON-LD with prefixes and context object val jsonldWithPrefixes = readOrWriteTextFile("", new File("test_data/resourcesR2RV2/NarrenschiffFirstPage.jsonld"), writeFile = false) - // expand JSONLD with JSONLD processor + // expand JSON-LD with JSON-LD processor val jsonldParsedExpanded = JsonLDUtil.parseJsonLD(jsonldWithPrefixes) // expected result after expansion @@ -75,17 +74,17 @@ class JSONLDHandlingV2R2RSpec extends R2RSpec { } - "produce the expected JSONLD context object (on the server side)" in { + "produce the expected JSON-LD context object (on the server side)" in { Get("/v2/resources/" + URLEncoder.encode("http://rdfh.ch/0803/7bbb8e59b703", "UTF-8")) ~> resourcesPath ~> check { assert(status == StatusCodes.OK, response.toString) - val receivedJSONLDAsScala: Map[IRI, Any] = JavaUtil.deepJavaToScala(JsonUtils.fromString(responseAs[String])).asInstanceOf[Map[IRI, Any]] + val receivedJson: JsObject = JsonParser(responseAs[String]).asJsObject - val expectedJSONLDAsScala: Map[IRI, Any] = JavaUtil.deepJavaToScala(JsonUtils.fromString(readOrWriteTextFile("", new File("test_data/resourcesR2RV2/NarrenschiffFirstPage.jsonld"), writeFile = false))).asInstanceOf[Map[String, Any]] + val expectedJson: JsObject = JsonParser(readOrWriteTextFile("", new File("test_data/resourcesR2RV2/NarrenschiffFirstPage.jsonld"), writeFile = false)).asJsObject - assert(receivedJSONLDAsScala("@context") == expectedJSONLDAsScala("@context"), "@context incorrect") + assert(receivedJson.fields("@context") == expectedJson.fields("@context"), "@context incorrect") } diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala index 7a868e88cb..89f4609471 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala @@ -42,6 +42,7 @@ import org.knora.webapi.sharedtestdata.SharedTestDataADM import org.knora.webapi.util._ import org.xmlunit.builder.{DiffBuilder, Input} import org.xmlunit.diff.Diff +import spray.json.JsonParser import scala.collection.mutable.ArrayBuffer import scala.concurrent.duration._ @@ -862,7 +863,7 @@ class ResourcesRouteV2E2ESpec extends E2ESpec(ResourcesRouteV2E2ESpec.config) { val updateResponse: HttpResponse = singleAwaitingRequest(updateRequest) val updateResponseAsString: String = responseToString(updateResponse) assert(updateResponse.status == StatusCodes.OK, updateResponseAsString) - assert(updateResponseAsString == SharedTestDataADM.successResponse("Resource metadata updated")) + assert(JsonParser(updateResponseAsString) == JsonParser(SharedTestDataADM.successResponse("Resource metadata updated"))) val previewRequest = Get(s"$baseApiUrl/v2/resourcespreview/${URLEncoder.encode(resourceIri, "UTF-8")}") ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password)) val previewResponse: HttpResponse = singleAwaitingRequest(previewRequest) @@ -897,7 +898,7 @@ class ResourcesRouteV2E2ESpec extends E2ESpec(ResourcesRouteV2E2ESpec.config) { val updateResponse: HttpResponse = singleAwaitingRequest(updateRequest) val updateResponseAsString: String = responseToString(updateResponse) assert(updateResponse.status == StatusCodes.OK, updateResponseAsString) - assert(updateResponseAsString == SharedTestDataADM.successResponse("Resource marked as deleted")) + assert(JsonParser(updateResponseAsString) == JsonParser(SharedTestDataADM.successResponse("Resource marked as deleted"))) val previewRequest = Get(s"$baseApiUrl/v2/resourcespreview/${URLEncoder.encode(resourceIri, "UTF-8")}") ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password)) val previewResponse: HttpResponse = singleAwaitingRequest(previewRequest) @@ -918,7 +919,7 @@ class ResourcesRouteV2E2ESpec extends E2ESpec(ResourcesRouteV2E2ESpec.config) { val updateResponse: HttpResponse = singleAwaitingRequest(updateRequest) val updateResponseAsString: String = responseToString(updateResponse) assert(updateResponse.status == StatusCodes.OK, updateResponseAsString) - assert(updateResponseAsString == SharedTestDataADM.successResponse("Resource marked as deleted")) + assert(JsonParser(updateResponseAsString) == JsonParser(SharedTestDataADM.successResponse("Resource marked as deleted"))) val previewRequest = Get(s"$baseApiUrl/v2/resourcespreview/${URLEncoder.encode(resourceIri, "UTF-8")}") ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password)) val previewResponse: HttpResponse = singleAwaitingRequest(previewRequest) diff --git a/webapi/src/test/scala/org/knora/webapi/util/AkkaHttpUtils.scala b/webapi/src/test/scala/org/knora/webapi/util/AkkaHttpUtils.scala index a1b2a4010f..24ef23fede 100644 --- a/webapi/src/test/scala/org/knora/webapi/util/AkkaHttpUtils.scala +++ b/webapi/src/test/scala/org/knora/webapi/util/AkkaHttpUtils.scala @@ -19,17 +19,11 @@ package org.knora.webapi.util -import java.io.ByteArrayInputStream -import java.util - import akka.actor.ActorSystem -import akka.event.LoggingAdapter import akka.http.scaladsl.model.{HttpResponse, StatusCodes} import akka.http.scaladsl.unmarshalling.Unmarshal import akka.stream.Materializer import akka.util.Timeout -import com.github.jsonldjava.core.{JsonLdOptions, JsonLdProcessor} -import com.github.jsonldjava.utils.JsonUtils import com.typesafe.scalalogging.LazyLogging import spray.json._ @@ -64,39 +58,4 @@ object AkkaHttpUtils extends LazyLogging { //FIXME: There is probably a better non blocking way of doing it. Await.result(jsonFuture, Timeout(10.seconds).duration) } - - /** - * Given an [[HttpResponse]] containing json-ld, return the said json-ld in expanded form. - * - * @param response the [[HttpResponse]] containing json - * @return an [[JsObject]] - */ - def httpResponseToJsonLDExpanded(response: HttpResponse)(implicit ec: ExecutionContext, system: ActorSystem, log: LoggingAdapter): Map[String, Any] = { - - implicit val materializer: Materializer = Materializer.matFromSystem(system) - - val jsonStringFuture: Future[String] = Unmarshal(response.entity).to[String] - - val jsonString = Await.result(jsonStringFuture, Timeout(1.second).duration) - - val istream = new ByteArrayInputStream(jsonString.getBytes(java.nio.charset.StandardCharsets.UTF_8)) - - val jsonObject: AnyRef = JsonUtils.fromInputStream(istream) - - val context = new util.HashMap() - - val options = new JsonLdOptions() - - val normalized: util.Map[String, Object] = JsonLdProcessor.compact(jsonObject, context, options) - - - /* - val opts: JsonLdOptions = new JsonLdOptions() - val expanded = JsonLdProcessor.expand(httpResponseToJson(response), opts) - println("expanded json-ld: " + expanded) - */ - - JavaUtil.deepJavaToScala(normalized).asInstanceOf[Map[String, Any]] - } - }