Skip to content

Commit

Permalink
even more endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
jnatten committed Dec 6, 2023
1 parent 9194622 commit 443cc9c
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
package no.ndla.myndlaapi.controller

import no.ndla.common.model.api
import no.ndla.myndla.model.api.{Folder, NewFolder}
import no.ndla.myndla.model.api.{Folder, NewFolder, NewResource, Resource, UpdatedFolder, UpdatedResource}
import no.ndla.myndla.model.domain.FolderStatus
import no.ndla.myndla.service.{FolderReadService, FolderWriteService}
import no.ndla.myndlaapi.Eff
import no.ndla.myndlaapi.service.ReadService
Expand Down Expand Up @@ -41,7 +42,8 @@ trait FolderController {
.description("Choose if sub-folders should be included in the response")
.default(false)

private val pathFolderId = path[UUID]("folder-id").description("The UUID of the folder")
private val pathFolderId = path[UUID]("folder-id").description("The UUID of the folder")
private val pathResourceId = path[UUID]("resource-id").description("The UUID of the resource")

import io.circe.generic.auto._

Expand Down Expand Up @@ -83,10 +85,121 @@ trait FolderController {
folderWriteService.newFolder(newFolder, feideHeader).handleErrorsOrOk
}

private def updateFolder: ServerEndpoint[Any, Eff] = endpoint.patch
.summary("Update folder with new data")
.description("Update folder with new data")
.in(feideHeader)
.in(pathFolderId)
.in(jsonBody[UpdatedFolder])
.errorOut(errorOutputsFor(400, 401, 403, 404))
.out(jsonBody[Folder])
.serverLogicPure { case (feideHeader, folderId, updatedFolder) =>
folderWriteService.updateFolder(folderId, updatedFolder, feideHeader).handleErrorsOrOk
}

private def removeFolder: ServerEndpoint[Any, Eff] = endpoint.delete
.summary("Remove folder from user folders")
.description("Remove folder from user folders")
.in(feideHeader)
.in(pathFolderId)
.errorOut(errorOutputsFor(400, 401, 403, 404))
.out(emptyOutput)
.serverLogicPure { case (feideHeader, folderId) =>
folderWriteService.deleteFolder(folderId, feideHeader).handleErrorsOrOk.map(_ => ())
}

val defaultSize = 5
val size = query[Int]("size")
.description("Limit the number of results to this many elements")
.default(defaultSize)

private def fetchAllResources: ServerEndpoint[Any, Eff] = endpoint.get
.summary("Fetch all resources that belongs to a user")
.description("Fetch all resources that belongs to a user")
.in("resources")
.in(feideHeader)
.in(size)
.errorOut(errorOutputsFor(400, 401, 403, 404))
.out(jsonBody[List[Resource]])
.serverLogicPure { case (feideHeader, inputSize) =>
val size = if (inputSize < 1) defaultSize else inputSize
folderReadService.getAllResources(size, feideHeader).handleErrorsOrOk
}

private def createFolderResource: ServerEndpoint[Any, Eff] = endpoint.post
.summary("Creates new folder resource")
.description("Creates new folder resource")
.in(feideHeader)
.in(pathFolderId / "resources")
.in(jsonBody[NewResource])
.errorOut(errorOutputsFor(400, 401, 403, 404))
.out(jsonBody[Resource])
.serverLogicPure { case (feideHeader, folderId, newResource) =>
folderWriteService.newFolderResourceConnection(folderId, newResource, feideHeader).handleErrorsOrOk
}

private def updateResource: ServerEndpoint[Any, Eff] = endpoint.patch
.summary("Updated selected resource")
.description("Updates selected resource")
.in("resources" / pathResourceId)
.in(feideHeader)
.in(jsonBody[UpdatedResource])
.errorOut(errorOutputsFor(400, 401, 403, 404))
.out(jsonBody[Resource])
.serverLogicPure { case (resourceId, feideHeader, updatedResource) =>
folderWriteService.updateResource(resourceId, updatedResource, feideHeader).handleErrorsOrOk
}

private def deleteResource: ServerEndpoint[Any, Eff] = endpoint.delete
.summary("Delete selected resource")
.description("Delete selected resource")
.in(feideHeader)
.in(pathFolderId / "resources" / pathResourceId)
.out(emptyOutput)
.errorOut(errorOutputsFor(400, 401, 403, 404, 502))
.serverLogicPure { case (feideHeader, folderId, resourceId) =>
folderWriteService
.deleteConnection(folderId, resourceId, feideHeader)
.handleErrorsOrOk
.map(_ => ())
}

private def fetchSharedFolder: ServerEndpoint[Any, Eff] = endpoint.get
.summary("Fetch a shared folder and all its content")
.description("Fetch a shared folder and all its content")
.in("shared" / pathFolderId)
.out(jsonBody[Folder])
.errorOut(errorOutputsFor(400, 401, 403, 404, 502))
.serverLogicPure { case (folderId) =>
folderReadService.getSharedFolder(folderId).handleErrorsOrOk

}

val folderStatus = query[FolderStatus.Value]("status").description("Status of the folder")
private def changeStatusForFolderAndSubFolders: ServerEndpoint[Any, Eff] = endpoint.patch
.summary("Change status for given folder and all its subfolders")
.description("Change status for given folder and all its subfolders")
.in("shared" / pathFolderId)
.in(folderStatus)
.in(feideHeader)
.out(jsonBody[List[UUID]])
.errorOut(errorOutputsFor(400, 401, 403, 404, 502))
.serverLogicPure { case (folderId, status, feideHeader) =>
folderWriteService.changeStatusOfFolderAndItsSubfolders(folderId, status, feideHeader).handleErrorsOrOk
}

override protected val endpoints: List[ServerEndpoint[Any, Eff]] = List(
getAllFolders,
getSingleFolder,
createNewFolder
createNewFolder,
updateFolder,
removeFolder,
fetchAllResources,
createFolderResource,
updateResource,
deleteResource,
fetchSharedFolder,
changeStatusForFolderAndSubFolders
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package no.ndla.myndlaapi.controller
import com.typesafe.scalalogging.StrictLogging
import no.ndla.common.Clock
import no.ndla.common.errors.{AccessDeniedException, NotFoundException}
import no.ndla.myndla.model.domain.InvalidStatusException
import no.ndla.myndlaapi.Props
import no.ndla.network.tapir.{AllErrors, ErrorBody, TapirErrorHelpers}

Expand All @@ -26,5 +27,7 @@ trait ErrorHelpers extends TapirErrorHelpers with StrictLogging {
ErrorBody(ACCESS_DENIED, a.getMessage, clock.now(), 401)
case a: AccessDeniedException =>
ErrorBody(ACCESS_DENIED, a.getMessage, clock.now(), 403)
case mse: InvalidStatusException =>
ErrorBody(MISSING_STATUS, mse.getMessage, clock.now(), 400)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

package no.ndla.myndla.model.domain

import sttp.tapir.CodecFormat.TextPlain
import sttp.tapir.{Codec, CodecFormat, DecodeResult, Schema}

import scala.util.{Failure, Success, Try}

object FolderStatus extends Enumeration {
val PRIVATE: FolderStatus.Value = Value("private")
val SHARED: FolderStatus.Value = Value("shared")

def all: Seq[String] = FolderStatus.values.map(_.toString).toSeq

def valueOf(s: String): Option[FolderStatus.Value] = {
FolderStatus.values.find(_.toString == s)
}
Expand All @@ -32,4 +36,15 @@ object FolderStatus extends Enumeration {
case Some(folderStatus) => Success(folderStatus)
}
}

implicit val schema: Schema[FolderStatus.Value] = Schema.string
implicit val queryParamCodec: Codec[List[String], Option[FolderStatus.Value], CodecFormat.TextPlain] = {
Codec
.id[List[String], TextPlain](TextPlain(), Schema.string)
.mapDecode(x =>
DecodeResult.Value(
valueOf(x.headOption)
)
)(x => x.map(_.toString).toList)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ trait TapirErrorHelpers extends StrictLogging {
val UNAUTHORIZED = "UNAUTHORIZED"
val FORBIDDEN = "FORBIDDEN"
val ACCESS_DENIED = "ACCESS DENIED"
val MISSING_STATUS = "INVALID_STATUS"
val IMPORT_FAILED = "IMPORT_FAILED"
val FILE_TOO_BIG = "FILE TOO BIG"
val DATABASE_UNAVAILABLE = "DATABASE_UNAVAILABLE"
Expand Down

0 comments on commit 443cc9c

Please sign in to comment.