Skip to content

Commit

Permalink
feat: creator's affiliation added to the Project Details response (#1069
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jachro authored Aug 19, 2022
1 parent fe92260 commit a704892
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ package object knowledgegraph {
import io.renku.graph.model.testentities
import io.renku.graph.model.testentities._
import io.renku.http.rest.Links.{Href, Link, Rel, _links}
import io.renku.json.JsonOps._
import io.renku.tinytypes.json.TinyTypeEncoders._

def fullJson(project: Project): Json = json"""{
"identifier": ${project.id.value},
Expand All @@ -50,60 +52,57 @@ package object knowledgegraph {
"jobArtifactsSize": ${project.statistics.jobArtifactsSize.value}
},
"version": ${project.entitiesProject.version.value}
}""" deepMerge {
_links(
Link(Rel.Self -> Href(renkuApiUrl / "projects" / project.path)),
Link(Rel("datasets") -> Href(renkuApiUrl / "projects" / project.path / "datasets"))
)
} deepMerge {
project.entitiesProject.maybeDescription
.map(description => json"""{"description": ${description.value} }""")
.getOrElse(Json.obj())
}
}"""
.deepMerge {
_links(
Link(Rel.Self -> Href(renkuApiUrl / "projects" / project.path)),
Link(Rel("datasets") -> Href(renkuApiUrl / "projects" / project.path / "datasets"))
)
}
.addIfDefined("description" -> project.entitiesProject.maybeDescription)

private implicit class UrlsOps(urls: Urls) {
import io.renku.json.JsonOps.JsonOps

lazy val toJson: Json = json"""{
"ssh": ${urls.ssh.value},
"http": ${urls.http.value},
"web": ${urls.web.value}
}""" addIfDefined ("readme" -> urls.maybeReadme.map(_.value))
"ssh": ${urls.ssh.value},
"http": ${urls.http.value},
"web": ${urls.web.value}
}""" addIfDefined ("readme" -> urls.maybeReadme)
}

private implicit lazy val forkingEncoder: Encoder[(ForksCount, testentities.RenkuProject)] =
Encoder.instance {
case (forksCount, project: testentities.RenkuProject.WithParent) => json"""{
"forksCount": ${forksCount.value},
"parent": {
"path": ${project.parent.path.value},
"name": ${project.parent.name.value},
"created": ${(project.parent.dateCreated, project.parent.maybeCreator)}
}
}"""
"forksCount": ${forksCount.value},
"parent": {
"path": ${project.parent.path.value},
"name": ${project.parent.name.value},
"created": ${(project.parent.dateCreated, project.parent.maybeCreator)}
}
}"""
case (forksCount, _) => json"""{
"forksCount": ${forksCount.value}
}"""
"forksCount": ${forksCount.value}
}"""
}

private implicit lazy val createdEncoder: Encoder[(DateCreated, Option[Person])] = Encoder.instance {
case (dateCreated, Some(creator)) => json"""{
"dateCreated": ${dateCreated.value},
"creator": $creator
"creator": $creator
}"""
case (dateCreated, _) => json"""{
"dateCreated": ${dateCreated.value}
}"""
}

private implicit lazy val personEncoder: Encoder[Person] = Encoder.instance {
case Person(name, Some(email), _, _, _) => json"""{
"name": ${name.value},
case Person(name, Some(email), _, _, maybeAffiliation) => json"""{
"name": ${name.value},
"email": ${email.value}
}"""
case Person(name, _, _, _, _) => json"""{
}""" addIfDefined ("affiliation" -> maybeAffiliation)
case Person(name, _, _, _, maybeAffiliation) => json"""{
"name": ${name.value}
}"""
}""" addIfDefined ("affiliation" -> maybeAffiliation)
}

private lazy val toJson: Permissions => Json = {
Expand Down
10 changes: 6 additions & 4 deletions knowledge-graph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,9 @@ Response body example for `Accept: application/json`:
"created": {
"dateCreated": "2001-09-05T10:48:29.457Z",
"creator": { // optional
"name": "author name",
"email": "author@mail.org" // optional
"name": "author name",
"email": "author@mail.org", // optional
"affiliation": "SDSC" // optional
}
},
"updatedAt": "2001-10-06T10:48:29.457Z",
Expand All @@ -602,8 +603,9 @@ Response body example for `Accept: application/json`:
"created": {
"dateCreated": "2001-09-04T10:48:29.457Z",
"creator": { // optional
"name": "parent author name",
"email": "parent.author@mail.org" // optional
"name": "parent author name",
"email": "parent.author@mail.org", // optional
"affiliation": "SDSC" // optional
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ private class EndpointDocsImpl(projectJsonEncoder: ProjectJsonEncoder, projectJs
Creation(
projects.DateCreated(Instant.parse("2012-11-15T10:00:00.000Z")),
Creator(persons.ResourceId("http://renkulab.io/persons/2"),
persons.Name("John"),
persons.Email("john@mail.com").some,
persons.Name("John")
persons.Affiliation("SDSC").some
).some
),
DateUpdated(Instant.parse("2012-11-16T10:00:00.000Z")),
Expand All @@ -110,8 +111,9 @@ private class EndpointDocsImpl(projectJsonEncoder: ProjectJsonEncoder, projectJs
Creation(
projects.DateCreated(Instant.parse("2012-11-17T10:00:00.000Z")),
Creator(persons.ResourceId("http://renkulab.io/persons/3"),
persons.Name("Goeff"),
persons.Email("goeff@mail.com").some,
persons.Name("Goeff")
persons.Affiliation("SDSC").some
).some
)
).some
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ private class KGProjectFinderImpl[F[_]: Async: Logger: SparqlQueryTimeRecorder](
name = "project by id",
Prefixes.of(schema -> "schema", prov -> "prov", renku -> "renku"),
s"""|SELECT ?resourceId ?name ?visibility ?maybeDescription ?dateCreated
| ?maybeCreatorResourceId ?maybeCreatorName ?maybeCreatorEmail
| ?maybeCreatorResourceId ?maybeCreatorName ?maybeCreatorEmail ?maybeCreatorAffiliation
| ?maybeParentResourceId ?maybeParentPath ?maybeParentName ?maybeParentDateCreated
| ?maybeParentCreatorResourceId ?maybeParentCreatorName ?maybeParentCreatorEmail
| ?maybeParentCreatorResourceId ?maybeParentCreatorName ?maybeParentCreatorEmail ?maybeParentCreatorAffiliation
| ?maybeSchemaVersion (GROUP_CONCAT(?keyword; separator=',') AS ?keywords)
|WHERE {
| ?resourceId a schema:Project;
Expand All @@ -67,6 +67,7 @@ private class KGProjectFinderImpl[F[_]: Async: Logger: SparqlQueryTimeRecorder](
| ?maybeCreatorResourceId a schema:Person;
| schema:name ?maybeCreatorName.
| OPTIONAL { ?maybeCreatorResourceId schema:email ?maybeCreatorEmail }
| OPTIONAL { ?maybeCreatorResourceId schema:affiliation ?maybeCreatorAffiliation }
| }
| OPTIONAL {
| ?resourceId prov:wasDerivedFrom ?maybeParentResourceId.
Expand All @@ -80,13 +81,14 @@ private class KGProjectFinderImpl[F[_]: Async: Logger: SparqlQueryTimeRecorder](
| ?maybeParentCreatorResourceId a schema:Person;
| schema:name ?maybeParentCreatorName.
| OPTIONAL { ?maybeParentCreatorResourceId schema:email ?maybeParentCreatorEmail }
| OPTIONAL { ?maybeParentCreatorResourceId schema:affiliation ?maybeParentCreatorAffiliation }
| }
| }
|}
|GROUP BY ?resourceId ?name ?visibility ?maybeDescription ?dateCreated
| ?maybeCreatorResourceId ?maybeCreatorName ?maybeCreatorEmail
| ?maybeCreatorResourceId ?maybeCreatorName ?maybeCreatorEmail ?maybeCreatorAffiliation
| ?maybeParentResourceId ?maybeParentPath ?maybeParentName ?maybeParentDateCreated
| ?maybeParentCreatorResourceId ?maybeParentCreatorName ?maybeParentCreatorEmail
| ?maybeParentCreatorResourceId ?maybeParentCreatorName ?maybeParentCreatorEmail ?maybeParentCreatorAffiliation
| ?maybeSchemaVersion
|""".stripMargin
)
Expand Down Expand Up @@ -121,30 +123,32 @@ private class KGProjectFinderImpl[F[_]: Async: Logger: SparqlQueryTimeRecorder](

ResultsDecoder[Option, KGProject] { implicit cur =>
for {
resourceId <- extract[ResourceId]("resourceId")
name <- extract[Name]("name")
visibility <- extract[Visibility]("visibility")
dateCreated <- extract[DateCreated]("dateCreated")
maybeDescription <- extract[Option[Description]]("maybeDescription")
keywords <- extract[Option[String]]("keywords").flatMap(toSetOfKeywords)
maybeCreatorResourceId <- extract[Option[persons.ResourceId]]("maybeCreatorResourceId")
maybeCreatorName <- extract[Option[persons.Name]]("maybeCreatorName")
maybeCreatorEmail <- extract[Option[persons.Email]]("maybeCreatorEmail")
maybeParentResourceId <- extract[Option[ResourceId]]("maybeParentResourceId")
maybeParentPath <- extract[Option[Path]]("maybeParentPath")
maybeParentName <- extract[Option[Name]]("maybeParentName")
maybeParentDateCreated <- extract[Option[DateCreated]]("maybeParentDateCreated")
maybeParentCreatorResourceId <- extract[Option[persons.ResourceId]]("maybeParentCreatorResourceId")
maybeParentCreatorName <- extract[Option[persons.Name]]("maybeParentCreatorName")
maybeParentCreatorEmail <- extract[Option[persons.Email]]("maybeParentCreatorEmail")
maybeVersion <- extract[Option[SchemaVersion]]("maybeSchemaVersion")
resourceId <- extract[ResourceId]("resourceId")
name <- extract[Name]("name")
visibility <- extract[Visibility]("visibility")
dateCreated <- extract[DateCreated]("dateCreated")
maybeDescription <- extract[Option[Description]]("maybeDescription")
keywords <- extract[Option[String]]("keywords").flatMap(toSetOfKeywords)
maybeCreatorResourceId <- extract[Option[persons.ResourceId]]("maybeCreatorResourceId")
maybeCreatorName <- extract[Option[persons.Name]]("maybeCreatorName")
maybeCreatorEmail <- extract[Option[persons.Email]]("maybeCreatorEmail")
maybeCreatorAffiliation <- extract[Option[persons.Affiliation]]("maybeCreatorAffiliation")
maybeParentResourceId <- extract[Option[ResourceId]]("maybeParentResourceId")
maybeParentPath <- extract[Option[Path]]("maybeParentPath")
maybeParentName <- extract[Option[Name]]("maybeParentName")
maybeParentDateCreated <- extract[Option[DateCreated]]("maybeParentDateCreated")
maybeParentCreatorResourceId <- extract[Option[persons.ResourceId]]("maybeParentCreatorResourceId")
maybeParentCreatorName <- extract[Option[persons.Name]]("maybeParentCreatorName")
maybeParentCreatorEmail <- extract[Option[persons.Email]]("maybeParentCreatorEmail")
maybeParentCreatorAffiliation <- extract[Option[persons.Affiliation]]("maybeParentCreatorAffiliation")
maybeVersion <- extract[Option[SchemaVersion]]("maybeSchemaVersion")
} yield KGProject(
resourceId,
path,
name,
ProjectCreation(dateCreated,
(maybeCreatorResourceId, maybeCreatorName).mapN { case (id, name) =>
ProjectCreator(id, maybeCreatorEmail, name)
ProjectCreator(id, name, maybeCreatorEmail, maybeCreatorAffiliation)
}
),
visibility,
Expand All @@ -154,10 +158,11 @@ private class KGProjectFinderImpl[F[_]: Async: Logger: SparqlQueryTimeRecorder](
parentId,
path,
name,
ProjectCreation(dateCreated,
(maybeParentCreatorResourceId, maybeParentCreatorName).mapN { case (id, name) =>
ProjectCreator(id, maybeParentCreatorEmail, name)
}
ProjectCreation(
dateCreated,
(maybeParentCreatorResourceId, maybeParentCreatorName).mapN { case (id, name) =>
ProjectCreator(id, name, maybeParentCreatorEmail, maybeParentCreatorAffiliation)
}
)
)
},
Expand Down Expand Up @@ -186,7 +191,11 @@ private object KGProjectFinder {

final case class KGParent(resourceId: ResourceId, path: Path, name: Name, created: ProjectCreation)

final case class ProjectCreator(resourceId: persons.ResourceId, maybeEmail: Option[persons.Email], name: persons.Name)
final case class ProjectCreator(resourceId: persons.ResourceId,
name: persons.Name,
maybeEmail: Option[persons.Email],
maybeAffiliation: Option[persons.Affiliation]
)

def apply[F[_]: Async: Logger: SparqlQueryTimeRecorder]: F[KGProjectFinder[F]] =
RenkuConnectionConfig[F]().map(new KGProjectFinderImpl(_))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ private class ProjectFinderImpl[F[_]: MonadThrow: Parallel: AccessTokenFinder](
visibility = kgProject.visibility,
created = Creation(
date = kgProject.created.date,
kgProject.created.maybeCreator.map(creator => Creator(creator.resourceId, creator.maybeEmail, creator.name))
kgProject.created.maybeCreator.map(creator =>
Creator(creator.resourceId, creator.name, creator.maybeEmail, creator.maybeAffiliation)
)
),
updatedAt = gitLabProject.updatedAt,
urls = gitLabProject.urls,
Expand All @@ -80,7 +82,9 @@ private class ProjectFinderImpl[F[_]: MonadThrow: Parallel: AccessTokenFinder](
path,
name,
Creation(created.date,
created.maybeCreator.map(creator => Creator(creator.resourceId, creator.maybeEmail, creator.name))
created.maybeCreator.map(creator =>
Creator(creator.resourceId, creator.name, creator.maybeEmail, creator.maybeAffiliation)
)
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,67 +66,69 @@ private class ProjectJsonEncoderImpl(renkuApiUrl: renku.ApiUrl) extends ProjectJ

private implicit lazy val creatorEncoder: Encoder[Creator] = Encoder.instance[Creator] { creator =>
json"""{
"name": ${creator.name}
}""" addIfDefined ("email" -> creator.maybeEmail)
"name": ${creator.name}
}"""
.addIfDefined("email" -> creator.maybeEmail)
.addIfDefined("affiliation" -> creator.maybeAffiliation)
}

private implicit lazy val urlsEncoder: Encoder[Urls] = Encoder.instance[Urls] { urls =>
json"""{
"ssh": ${urls.ssh},
"http": ${urls.http},
"web": ${urls.web}
}""" addIfDefined ("readme" -> urls.maybeReadme)
"ssh": ${urls.ssh},
"http": ${urls.http},
"web": ${urls.web}
}""" addIfDefined ("readme" -> urls.maybeReadme)
}

private implicit lazy val forkingEncoder: Encoder[Forking] = Encoder.instance[Forking] { forks =>
json"""{
"forksCount": ${forks.forksCount}
}""" addIfDefined ("parent" -> forks.maybeParent)
"forksCount": ${forks.forksCount}
}""" addIfDefined ("parent" -> forks.maybeParent)
}

private implicit lazy val parentProjectEncoder: Encoder[ParentProject] = Encoder.instance[ParentProject] { parent =>
json"""{
"path": ${parent.path},
"name": ${parent.name},
"created": ${parent.created}
}"""
"path": ${parent.path},
"name": ${parent.name},
"created": ${parent.created}
}"""
}

private implicit lazy val creationEncoder: Encoder[Creation] = Encoder.instance[Creation] { created =>
json"""{
"dateCreated": ${created.date}
}""" addIfDefined ("creator" -> created.maybeCreator)
"dateCreated": ${created.date}
}""" addIfDefined ("creator" -> created.maybeCreator)
}

private implicit lazy val permissionsEncoder: Encoder[Permissions] = Encoder.instance[Permissions] {
case ProjectAndGroupPermissions(projectAccessLevel, groupAccessLevel) => json"""{
"projectAccess": ${projectAccessLevel.accessLevel},
"groupAccess": ${groupAccessLevel.accessLevel}
}"""
"projectAccess": ${projectAccessLevel.accessLevel},
"groupAccess": ${groupAccessLevel.accessLevel}
}"""
case ProjectPermissions(accessLevel) => json"""{
"projectAccess": ${accessLevel.accessLevel}
}"""
"projectAccess": ${accessLevel.accessLevel}
}"""
case GroupPermissions(accessLevel) => json"""{
"groupAccess": ${accessLevel.accessLevel}
}"""
"groupAccess": ${accessLevel.accessLevel}
}"""
}

private implicit lazy val accessLevelEncoder: Encoder[AccessLevel] = Encoder.instance[AccessLevel] { level =>
json"""{
"level": {
"name": ${level.name.value},
"value": ${level.value.value}
}
}"""
"level": {
"name": ${level.name.value},
"value": ${level.value.value}
}
}"""
}

private implicit lazy val statisticsEncoder: Encoder[Statistics] = Encoder.instance[Statistics] { stats =>
json"""{
"commitsCount": ${stats.commitsCount},
"storageSize": ${stats.storageSize},
"repositorySize": ${stats.repositorySize},
"lfsObjectsSize": ${stats.lsfObjectsSize},
"jobArtifactsSize": ${stats.jobArtifactsSize}
}"""
"commitsCount": ${stats.commitsCount},
"storageSize": ${stats.storageSize},
"repositorySize": ${stats.repositorySize},
"lfsObjectsSize": ${stats.lsfObjectsSize},
"jobArtifactsSize": ${stats.jobArtifactsSize}
}"""
}
}
Loading

0 comments on commit a704892

Please sign in to comment.