Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: GroupsResponderADM cleanup (DEV-3292) #3139

Merged
merged 24 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.knora.webapi.routing._
import org.knora.webapi.slice.admin.AdminModule
import org.knora.webapi.slice.admin.api.AdminApiModule
import org.knora.webapi.slice.admin.api._
import org.knora.webapi.slice.admin.api.service.GroupsRestService
import org.knora.webapi.slice.admin.api.service.PermissionsRestService
import org.knora.webapi.slice.admin.api.service.ProjectRestService
import org.knora.webapi.slice.admin.api.service.UsersRestService
Expand Down Expand Up @@ -86,14 +87,14 @@ object LayersTest {
type CommonR =
ApiRoutes & AdminApiEndpoints & ApiV2Endpoints & AppRouter & AssetPermissionsResponder & Authenticator &
AuthorizationRestService & CacheServiceRequestMessageHandler & CardinalityHandler & ConstructResponseUtilV2 &
DspIngestClient & GravsearchTypeInspectionRunner & GroupsResponderADM & HttpServer & IIIFRequestMessageHandler &
InferenceOptimizationService & IriConverter & ListsResponder & ListsResponderV2 & MessageRelay & OntologyCache &
OntologyHelpers & OntologyInferencer & OntologyRepo & OntologyResponderV2 & PermissionUtilADM &
PermissionsResponderADM & PermissionsRestService & ProjectExportService & ProjectExportStorageService &
ProjectImportService & ProjectService & ProjectRestService & QueryTraverser & RepositoryUpdater &
ResourceUtilV2 & ResourcesResponderV2 & RestCardinalityService & SearchApiRoutes & SearchResponderV2 &
StandoffResponderV2 & StandoffTagUtilV2 & State & TestClientService & TriplestoreService & UserService &
UsersResponder & UsersRestService & ValuesResponderV2
DspIngestClient & GravsearchTypeInspectionRunner & GroupsResponderADM & GroupsRestService & GroupService &
HttpServer & IIIFRequestMessageHandler & InferenceOptimizationService & IriConverter & ListsResponder &
ListsResponderV2 & MessageRelay & OntologyCache & OntologyHelpers & OntologyInferencer & OntologyRepo &
OntologyResponderV2 & PermissionUtilADM & PermissionsResponderADM & PermissionsRestService & ProjectExportService &
ProjectExportStorageService & ProjectImportService & ProjectService & ProjectRestService & QueryTraverser &
RepositoryUpdater & ResourceUtilV2 & ResourcesResponderV2 & RestCardinalityService & SearchApiRoutes &
SearchResponderV2 & StandoffResponderV2 & StandoffTagUtilV2 & State & TestClientService & TriplestoreService &
UserService & UsersResponder & UsersRestService & ValuesResponderV2

private val commonLayersForAllIntegrationTests =
ZLayer.makeSome[CommonR0, CommonR](
Expand All @@ -114,7 +115,7 @@ object LayersTest {
ConstructTransformer.layer,
DspIngestClientLive.layer,
GravsearchTypeInspectionRunner.layer,
GroupsResponderADMLive.layer,
GroupsResponderADM.layer,
HandlerMapper.layer,
HttpServer.layer,
IIIFRequestMessageHandlerLive.layer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,44 @@ import org.knora.webapi.sharedtestdata.SharedTestDataADM._
import org.knora.webapi.slice.admin.api.GroupsRequests.GroupCreateRequest
import org.knora.webapi.slice.admin.api.GroupsRequests.GroupStatusUpdateRequest
import org.knora.webapi.slice.admin.api.GroupsRequests.GroupUpdateRequest
import org.knora.webapi.slice.admin.api.service.GroupsRestService
import org.knora.webapi.slice.admin.domain.model.GroupDescriptions
import org.knora.webapi.slice.admin.domain.model.GroupIri
import org.knora.webapi.slice.admin.domain.model.GroupName
import org.knora.webapi.slice.admin.domain.model.GroupSelfJoin
import org.knora.webapi.slice.admin.domain.model.GroupStatus
import org.knora.webapi.slice.admin.domain.model.KnoraProject.ProjectIri
import org.knora.webapi.slice.admin.domain.service.GroupService
import org.knora.webapi.util.MutableTestIri
import org.knora.webapi.util.ZioScalaTestUtil.assertFailsWithA

/**
* This spec is used to test the messages received by the [[GroupsResponderADMSpec]] actor.
*/
class GroupsResponderADMSpec extends CoreSpec {
private val groupRestService = ZIO.serviceWithZIO[GroupsRestService]
private val groupService = ZIO.serviceWithZIO[GroupService]

"The GroupsResponder " when {
"asked about all groups" should {
"return a list" in {
val groups = UnsafeZioRun.runOrThrow(ZIO.serviceWithZIO[GroupsResponderADM](_.groupsGetADM))
assert(groups.nonEmpty)
assert(groups.size == 2)
val response = UnsafeZioRun.runOrThrow(groupRestService(_.getGroups))
assert(response.groups.nonEmpty)
assert(response.groups.size == 2)
}
}

"asked about a group identified by 'iri' " should {
"return group info if the group is known " in {
val group =
UnsafeZioRun.runOrThrow(ZIO.serviceWithZIO[GroupsResponderADM](_.groupGetADM(imagesReviewerGroup.id)))
assert(group.nonEmpty)
assert(group.map(_.id).contains(imagesReviewerGroup.id))
val iri = GroupIri.unsafeFrom(imagesReviewerGroup.id)
val response = UnsafeZioRun.runOrThrow(groupService(_.findById(iri)))
assert(response.nonEmpty)
assert(response.map(_.id).contains(imagesReviewerGroup.id))
}

"return 'None' when the group is unknown " in {
val iri = "http://rdfh.ch/groups/notexisting"
val response = UnsafeZioRun.runOrThrow(ZIO.serviceWithZIO[GroupsResponderADM](_.groupGetADM(iri)))
val iri = GroupIri.unsafeFrom("http://rdfh.ch/groups/0987/notexisting")
val response = UnsafeZioRun.runOrThrow(groupService(_.findById(iri)))
assert(response.isEmpty)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.knora.webapi.routing._
import org.knora.webapi.slice.admin.AdminModule
import org.knora.webapi.slice.admin.api.AdminApiModule
import org.knora.webapi.slice.admin.api._
import org.knora.webapi.slice.admin.api.service.GroupsRestService
import org.knora.webapi.slice.admin.api.service.PermissionsRestService
import org.knora.webapi.slice.admin.api.service.ProjectRestService
import org.knora.webapi.slice.admin.api.service.UsersRestService
Expand Down Expand Up @@ -72,7 +73,7 @@ object LayersLive {
ActorSystem & AdminApiEndpoints & ApiRoutes & ApiV2Endpoints & AppConfigurations & AppRouter &
AssetPermissionsResponder & Authenticator & AuthorizationRestService &
CacheServiceRequestMessageHandler & CardinalityHandler & ConstructResponseUtilV2 &
GravsearchTypeInspectionRunner & GroupsResponderADM & HttpServer &
GravsearchTypeInspectionRunner & GroupsResponderADM & GroupsRestService & GroupService & HttpServer &
IIIFRequestMessageHandler & InferenceOptimizationService & InstrumentationServerConfig & IriConverter &
JwtService & ListsResponder & ListsResponderV2 & MessageRelay & OntologyCache & OntologyHelpers &
OntologyInferencer & OntologyResponderV2 & PermissionsResponderADM & PermissionsRestService &
Expand Down Expand Up @@ -105,7 +106,7 @@ object LayersLive {
ConstructTransformer.layer,
DspIngestClientLive.layer,
GravsearchTypeInspectionRunner.layer,
GroupsResponderADMLive.layer,
GroupsResponderADM.layer,
HandlerMapper.layer,
HttpServer.layer,
IIIFRequestMessageHandlerLive.layer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ import org.knora.webapi.slice.admin.domain.model.Group
*/
sealed trait GroupsResponderRequestADM extends KnoraRequestADM with RelayedMessage

/**
* Get everything about a single group identified through its IRI. A successful response will be
* an [[Option[GroupADM] ]], which will be `None` if the group was not found.
*
* @param groupIri IRI of the group.
*/
case class GroupGetADM(groupIri: IRI) extends GroupsResponderRequestADM

/**
* Get everything about a multiple groups identified by their IRIs. The response will be a
* [[Set[GroupGetResponseADM] ]], or an error if one or more groups was not found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,106 +46,14 @@
import org.knora.webapi.store.triplestore.api.TriplestoreService.Queries._
import org.knora.webapi.util.ZioHelper

/**
* Returns information about groups.
*/
trait GroupsResponderADM {

/**
* Gets all the groups (without built-in groups) and returns them as a sequence of [[Group]].
*
* @return all the groups as a sequence of [[Group]].
*/
def groupsGetADM: Task[Seq[Group]]

/**
* Gets the group with the given group IRI and returns the information as a [[Group]].
*
* @param groupIri the IRI of the group requested.
* @return information about the group as a [[Group]]
*/
def groupGetADM(groupIri: IRI): Task[Option[Group]]

/**
* Gets the groups with the given IRIs and returns a set of [[GroupGetResponseADM]] objects.
*
* @param groupIris the IRIs of the groups being requested
* @return information about the group as a set of [[GroupGetResponseADM]] objects.
*/
def multipleGroupsGetRequestADM(groupIris: Set[IRI]): Task[Set[GroupGetResponseADM]]

/**
* Gets the group members with the given group IRI and returns the information as a [[GroupMembersGetResponseADM]].
* Only project and system admins are allowed to access this information.
*
* @param iri the IRI of the group.
* @param user the user initiating the request.
* @return A [[GroupMembersGetResponseADM]]
*/
def groupMembersGetRequest(iri: GroupIri, user: User): Task[GroupMembersGetResponseADM]

/**
* Create a new group.
*
* @param request the create request information.
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]]
*/
def createGroup(
request: GroupCreateRequest,
apiRequestID: UUID,
): Task[GroupGetResponseADM]

/**
* Change group's basic information.
*
* @param groupIri the IRI of the group we want to change.
* @param request the change request.
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]].
*/
def updateGroup(
groupIri: GroupIri,
request: GroupUpdateRequest,
apiRequestID: UUID,
): Task[GroupGetResponseADM]

/**
* Change group's status.
*
* @param groupIri the IRI of the group we want to change.
* @param request the change request.
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]].
*/
def updateGroupStatus(
groupIri: GroupIri,
request: GroupStatusUpdateRequest,
apiRequestID: UUID,
): Task[GroupGetResponseADM]

/**
* Delete a group by changing its status to 'false'.
*
* @param iri the IRI of the group to be deleted.
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]].
*/
def deleteGroup(
iri: GroupIri,
apiRequestID: UUID,
): Task[GroupGetResponseADM]
}

final case class GroupsResponderADMLive(
final case class GroupsResponderADM(
triplestore: TriplestoreService,
messageRelay: MessageRelay,
iriService: IriService,
knoraUserService: KnoraUserService,
projectService: ProjectService,
implicit val stringFormatter: StringFormatter,
) extends GroupsResponderADM
with MessageHandler
) extends MessageHandler
with GroupsADMJsonProtocol
with LazyLogging {

Expand All @@ -155,25 +63,10 @@
* Receives a message extending [[GroupsResponderRequestADM]], and returns an appropriate response message
*/
def handle(msg: ResponderRequest): Task[Any] = msg match {
case r: GroupGetADM => groupGetADM(r.groupIri)
case r: MultipleGroupsGetRequestADM => multipleGroupsGetRequestADM(r.groupIris)
case other => Responder.handleUnexpectedMessage(other, this.getClass.getName)
}

/**
* Gets all the groups (without built-in groups) and returns them as a sequence of [[Group]].
*
* @return all the groups as a sequence of [[Group]].
*/
override def groupsGetADM: Task[Seq[Group]] = {
val query = Construct(sparql.admin.txt.getGroups(None))
for {
groupsResponse <- triplestore.query(query).flatMap(_.asExtended)
groups = groupsResponse.statements.map(convertStatementsToGroupADM)
result <- ZioHelper.sequence(groups.toSeq)
} yield result.sorted
}

private def convertStatementsToGroupADM(statements: (SubjectV2, ConstructPredicateObjects)): Task[Group] = {
val groupIri: SubjectV2 = statements._1
val propertiesMap: ConstructPredicateObjects = statements._2
Expand Down Expand Up @@ -211,7 +104,7 @@
* @param groupIri the IRI of the group requested.
* @return information about the group as a [[Group]]
*/
override def groupGetADM(groupIri: IRI): Task[Option[Group]] = {
private def groupGetADM(groupIri: IRI): Task[Option[Group]] = {
val query = Construct(sparql.admin.txt.getGroups(maybeIri = Some(groupIri)))
for {
statements <- triplestore.query(query).flatMap(_.asExtended).map(_.statements.headOption)
Expand All @@ -225,7 +118,7 @@
* @param groupIris the IRIs of the groups being requested
* @return information about the group as a set of [[GroupGetResponseADM]] objects.
*/
override def multipleGroupsGetRequestADM(groupIris: Set[IRI]): Task[Set[GroupGetResponseADM]] =
private def multipleGroupsGetRequestADM(groupIris: Set[IRI]): Task[Set[GroupGetResponseADM]] =
ZioHelper.sequence(groupIris.map { iri =>
groupGetADM(iri)
.flatMap(ZIO.fromOption(_))
Expand Down Expand Up @@ -289,7 +182,7 @@
* @param user the user initiating the request.
* @return A [[GroupMembersGetResponseADM]]
*/
override def groupMembersGetRequest(iri: GroupIri, user: User): Task[GroupMembersGetResponseADM] =
def groupMembersGetRequest(iri: GroupIri, user: User): Task[GroupMembersGetResponseADM] =
groupMembersGetADM(iri.value, user).map(GroupMembersGetResponseADM.apply)

/**
Expand All @@ -299,7 +192,7 @@
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]]
*/
override def createGroup(
def createGroup(
request: GroupCreateRequest,
apiRequestID: UUID,
): Task[GroupGetResponseADM] = {
Expand Down Expand Up @@ -352,7 +245,7 @@
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]].
*/
override def updateGroup(
def updateGroup(
groupIri: GroupIri,
request: GroupUpdateRequest,
apiRequestID: UUID,
Expand All @@ -371,7 +264,7 @@
* @param apiRequestID the unique request ID.
* @return a [[GroupGetResponseADM]].
*/
override def updateGroupStatus(
def updateGroupStatus(
groupIri: GroupIri,
request: GroupStatusUpdateRequest,
apiRequestID: UUID,
Expand All @@ -386,7 +279,7 @@
IriLocker.runWithIriLock(apiRequestID, groupIri.value, task)
}

override def deleteGroup(
def deleteGroup(
iri: GroupIri,
apiRequestID: UUID,
): Task[GroupGetResponseADM] = {
Expand Down Expand Up @@ -490,7 +383,7 @@
}
}

object GroupsResponderADMLive {
object GroupsResponderADM {
val layer = ZLayer.fromZIO {
for {
ts <- ZIO.service[TriplestoreService]
Expand All @@ -499,7 +392,7 @@
kus <- ZIO.service[KnoraUserService]
ps <- ZIO.service[ProjectService]
mr <- ZIO.service[MessageRelay]
handler <- mr.subscribe(GroupsResponderADMLive(ts, mr, iris, kus, ps, sf))
handler <- mr.subscribe(GroupsResponderADM(ts, mr, iris, kus, ps, sf))

Check warning on line 395 in webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala

View check run for this annotation

Codecov / codecov/patch

webapi/src/main/scala/org/knora/webapi/responders/admin/GroupsResponderADM.scala#L395

Added line #L395 was not covered by tests
} yield handler
}
}