Skip to content

Commit

Permalink
feat: Add resources/info endpoint (DEV-792) (#2309)
Browse files Browse the repository at this point in the history
Co-authored-by: irinaschubert <irina.schubert@dasch.swiss>
  • Loading branch information
seakayone and irinaschubert committed Dec 19, 2022
1 parent 94836e8 commit c3f96a9
Show file tree
Hide file tree
Showing 34 changed files with 1,070 additions and 92 deletions.
12 changes: 12 additions & 0 deletions webapi/src/it/scala/org/knora/webapi/core/LayersTest.scala
Expand Up @@ -6,7 +6,11 @@ import zio.ZLayer
import org.knora.webapi.auth.JWTService
import org.knora.webapi.config.AppConfig
import org.knora.webapi.config.AppConfigForTestContainers
import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.routing.ApiRoutes
import org.knora.webapi.slice.resourceinfo.api.RestResourceInfoService
import org.knora.webapi.slice.resourceinfo.domain.IriConverter
import org.knora.webapi.slice.resourceinfo.domain.ResourceInfoRepo
import org.knora.webapi.store.cache.CacheServiceManager
import org.knora.webapi.store.cache.api.CacheService
import org.knora.webapi.store.cache.impl.CacheServiceInMemImpl
Expand Down Expand Up @@ -37,8 +41,12 @@ object LayersTest {
with CacheServiceManager
with HttpServer
with IIIFServiceManager
with IriConverter
with RepositoryUpdater
with ResourceInfoRepo
with RestResourceInfoService
with State
with StringFormatter
with TestClientService
with TriplestoreService
with TriplestoreServiceManager
Expand All @@ -51,8 +59,12 @@ object LayersTest {
CacheServiceManager.layer,
HttpServer.layer,
IIIFServiceManager.layer,
IriConverter.layer,
RepositoryUpdater.layer,
ResourceInfoRepo.layer,
RestResourceInfoService.layer,
State.layer,
StringFormatter.test,
TestClientService.layer,
TriplestoreServiceHttpConnectorImpl.layer,
TriplestoreServiceManager.layer
Expand Down
Expand Up @@ -58,7 +58,7 @@ class ResourcesV1R2RSpec extends R2RSpec {
private val resourcesPathV1 =
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV1(routeData).makeRoute)
private val resourcesPathV2 =
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData).makeRoute)
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData, null).makeRoute)
private val valuesPathV1 =
DSPApiDirectives.handleErrors(system, appConfig)(new ValuesRouteV1(routeData).makeRoute)

Expand Down
Expand Up @@ -25,7 +25,7 @@ import org.knora.webapi.routing.v2.ResourcesRouteV2
*/
class JSONLDHandlingV2R2RSpec extends R2RSpec {

private val resourcesPath = new ResourcesRouteV2(routeData).makeRoute
private val resourcesPath = new ResourcesRouteV2(routeData, null).makeRoute

implicit def default(implicit system: ActorSystem): RouteTestTimeout = RouteTestTimeout(
appConfig.defaultTimeoutAsDuration
Expand Down
Expand Up @@ -66,7 +66,7 @@ class OntologyV2R2RSpec extends R2RSpec {
private val ontologiesPath =
DSPApiDirectives.handleErrors(system, appConfig)(new OntologiesRouteV2(routeData).makeRoute)
private val resourcesPath =
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData).makeRoute)
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData, null).makeRoute)

implicit def default(implicit system: ActorSystem): RouteTestTimeout = RouteTestTimeout(
appConfig.defaultTimeoutAsDuration
Expand Down
Expand Up @@ -54,7 +54,7 @@ class SearchRouteV2R2RSpec extends R2RSpec {
private val searchPath =
DSPApiDirectives.handleErrors(system, appConfig)(new SearchRouteV2(routeData).makeRoute)
private val resourcePath =
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData).makeRoute)
DSPApiDirectives.handleErrors(system, appConfig)(new ResourcesRouteV2(routeData, null).makeRoute)
private val standoffPath =
DSPApiDirectives.handleErrors(system, appConfig)(new StandoffRouteV2(routeData).makeRoute)
private val valuesPath =
Expand Down
@@ -0,0 +1,22 @@
package org.knora.webapi.slice.resourceinfo.api

import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.slice.resourceinfo.domain
import org.knora.webapi.slice.resourceinfo.domain.{InternalIri, IriConverter}
import zio.test._

object IriConverterLiveSpec extends ZIOSpecDefault {

def spec = suite("IriConverterLive")(
test("should not convert the projectIri") {
for {
internal <- IriConverter.asInternalIri("http://project-iri")
} yield assertTrue(internal == domain.InternalIri("http://project-iri"))
},
test("should convert a resourceClassIri") {
for {
internal <- IriConverter.asInternalIri("http://0.0.0.0:3333/ontology/0001/anything/v2#Thing")
} yield assertTrue(internal == InternalIri("http://www.knora.org/ontology/0001/anything#Thing"))
}
).provide(IriConverter.layer, StringFormatter.test)
}
Expand Up @@ -8,9 +8,12 @@ package org.knora.webapi.store.triplestore.upgrade.plugins
import com.typesafe.scalalogging.Logger
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

import scala.util.Failure
import scala.util.Success
import java.io.BufferedInputStream
import java.io.ByteArrayInputStream
import java.io.FileInputStream
import scala.util.Using

import org.knora.webapi.messages.util.ErrorHandlingMap
import org.knora.webapi.messages.util.rdf._
Expand All @@ -37,6 +40,18 @@ abstract class UpgradePluginSpec extends AnyWordSpecLike with Matchers {
rdfModel
}

/**
* Parses a TriG String and returns it as an [[RdfModel]].
*
* @param s the [[String]] content of a "TriG file".
* @return an [[RdfModel]].
*/
def stringToModel(s: String): RdfModel =
Using(new ByteArrayInputStream(s.getBytes))(rdfFormatUtil.inputStreamToRdfModel(_, TriG)) match {
case Success(value) => value
case Failure(e) => throw new IllegalArgumentException("Invalid model", e)
}

/**
* Wraps expected SPARQL SELECT results in a [[SparqlSelectResultBody]].
*
Expand Down
10 changes: 3 additions & 7 deletions webapi/src/main/scala/org/knora/webapi/config/AppConfig.scala
Expand Up @@ -8,6 +8,8 @@ package org.knora.webapi.config
import com.typesafe.config.ConfigFactory
import zio._
import zio.config._
import zio.config.magnolia._
import zio.config.typesafe._

import java.nio.file.Files
import java.nio.file.Path
Expand All @@ -19,13 +21,9 @@ import scala.util.Success
import scala.util.Try

import dsp.errors.FileWriteException
import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.messages.util.rdf.RdfFeatureFactory
import org.knora.webapi.util.cache.CacheUtil

import typesafe._
import magnolia._

/**
* Represents the configuration as defined in application.conf.
*/
Expand Down Expand Up @@ -272,7 +270,6 @@ object AppConfig {
for {
c <- configFromSource.orDie
_ <- ZIO.attempt(RdfFeatureFactory.init(c)).orDie // needs early init before first usage
_ <- ZIO.attempt(StringFormatter.init(c)).orDie // needs early init before first usage
} yield c
}.tap(_ => ZIO.logInfo(">>> AppConfig Live Initialized <<<"))

Expand All @@ -283,8 +280,7 @@ object AppConfig {
ZLayer {
for {
c <- configFromSource.orDie
_ <- ZIO.attempt(RdfFeatureFactory.init(c)).orDie // needs early init before first usage
_ <- ZIO.attempt(StringFormatter.initForTest()).orDie // needs early init before first usage
_ <- ZIO.attempt(RdfFeatureFactory.init(c)).orDie // needs early init before first usage
} yield c
}.tap(_ => ZIO.logInfo(">>> AppConfig Test Initialized <<<"))

Expand Down
26 changes: 15 additions & 11 deletions webapi/src/main/scala/org/knora/webapi/core/HttpServerZ.scala
Expand Up @@ -4,24 +4,28 @@
*/

package org.knora.webapi.core
import zhttp.http.HttpApp
import zhttp.service.Server
import zio.ZLayer
import zio._

import org.knora.webapi.config.AppConfig
import org.knora.webapi.routing.admin.ProjectsRouteZ
import org.knora.webapi.slice.resourceinfo.api.ResourceInfoRoute

object HttpServerZ {

val layer: ZLayer[AppRouter & AppConfig & State & ProjectsRouteZ, Nothing, Unit] =
ZLayer {
for {
appConfig <- ZIO.service[AppConfig]
projectsRoute <- ZIO.service[ProjectsRouteZ]
r = projectsRoute.route
port = appConfig.knoraApi.externalZioPort
_ <- Server.start(port, r).forkDaemon
_ <- ZIO.logInfo(">>> Acquire ZIO HTTP Server <<<")
} yield ()
}
private val apiRoutes: URIO[ResourceInfoRoute with ProjectsRouteZ, HttpApp[Any, Nothing]] = for {
projectsRoute <- ZIO.service[ProjectsRouteZ].map(_.route)
riRoute <- ZIO.service[ResourceInfoRoute].map(_.route)
} yield projectsRoute ++ riRoute

val layer: ZLayer[ResourceInfoRoute with ProjectsRouteZ with AppConfig, Nothing, Unit] = ZLayer {
for {
port <- ZIO.service[AppConfig].map(_.knoraApi.externalZioPort)
routes <- apiRoutes
_ <- Server.start(port, routes).forkDaemon
_ <- ZIO.logInfo(">>> Acquire ZIO HTTP Server <<<")
} yield ()
}
}
@@ -1,3 +1,8 @@
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.core

import zhttp.service.Server
Expand Down
16 changes: 13 additions & 3 deletions webapi/src/main/scala/org/knora/webapi/core/LayersLive.scala
Expand Up @@ -10,8 +10,13 @@ import zio.ZLayer

import org.knora.webapi.auth.JWTService
import org.knora.webapi.config.AppConfig
import org.knora.webapi.messages.StringFormatter
import org.knora.webapi.routing.ApiRoutes
import org.knora.webapi.routing.admin.ProjectsRouteZ
import org.knora.webapi.slice.resourceinfo.api.ResourceInfoRoute
import org.knora.webapi.slice.resourceinfo.api.RestResourceInfoService
import org.knora.webapi.slice.resourceinfo.domain.IriConverter
import org.knora.webapi.slice.resourceinfo.domain.ResourceInfoRepo
import org.knora.webapi.store.cache.CacheServiceManager
import org.knora.webapi.store.cache.api.CacheService
import org.knora.webapi.store.cache.impl.CacheServiceInMemImpl
Expand Down Expand Up @@ -53,17 +58,22 @@ object LayersLive {
ApiRoutes.layer,
AppConfig.live,
AppRouter.layer,
CacheServiceManager.layer,
CacheServiceInMemImpl.layer,
CacheServiceManager.layer,
HttpServer.layer,
HttpServerZ.layer, // this is the new ZIO HTTP server layer
IIIFServiceManager.layer,
IIIFServiceSipiImpl.layer,
IriConverter.layer,
JWTService.layer,
ProjectsRouteZ.layer,
RepositoryUpdater.layer,
ResourceInfoRepo.layer,
ResourceInfoRoute.layer,
RestResourceInfoService.layer,
State.layer,
TriplestoreServiceManager.layer,
StringFormatter.live,
TriplestoreServiceHttpConnectorImpl.layer,
ProjectsRouteZ.layer
TriplestoreServiceManager.layer
)
}
@@ -1,3 +1,8 @@
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.instrumentation.index

import zhttp.html.Html
Expand Down
@@ -1,3 +1,8 @@
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.instrumentation.prometheus

import zhttp.http._
Expand Down
Expand Up @@ -13,6 +13,7 @@ import com.google.gwt.safehtml.shared.UriUtils._
import com.typesafe.scalalogging.Logger
import org.apache.commons.lang3.StringUtils
import spray.json._
import zio.ZLayer

import java.nio.ByteBuffer
import java.time._
Expand Down Expand Up @@ -311,6 +312,16 @@ object StringFormatter {
creationFun()
})
)

val live: ZLayer[AppConfig, Nothing, StringFormatter] = ZLayer.fromFunction { appConfig: AppConfig =>
StringFormatter.init(appConfig)
StringFormatter.getGeneralInstance
}

val test: ZLayer[Any, Nothing, StringFormatter] = ZLayer.fromFunction { () =>
StringFormatter.initForTest()
StringFormatter.getGeneralInstance
}
}

/**
Expand Down Expand Up @@ -345,6 +356,8 @@ sealed trait SmartIri extends Ordered[SmartIri] with KnoraContentV2[SmartIri] {
*/
def toSparql: String

def toIri: IRI = toString

/**
* Returns `true` if this is a Knora data or definition IRI.
*/
Expand Down Expand Up @@ -485,6 +498,8 @@ sealed trait SmartIri extends Ordered[SmartIri] with KnoraContentV2[SmartIri] {
*/
override def toOntologySchema(targetSchema: OntologySchema): SmartIri

def internalIri: IRI = toOntologySchema(InternalSchema).toIri

/**
* Constructs a short prefix label for the ontology that the IRI belongs to.
*/
Expand Down

0 comments on commit c3f96a9

Please sign in to comment.