Skip to content

Commit

Permalink
feat(api): new endpoint /mySubmissions
Browse files Browse the repository at this point in the history
New endpoint `/moderationrequest/mySubmissions` to get moderation
requests submitted by the user.

Also, refactor the `ModerationRequestController` to use
`ModerationRequestController.getModerationResponseEntity()`

Signed-off-by: Gaurav Mishra <[email protected]>
  • Loading branch information
GMishx committed Jan 16, 2024
1 parent e6dc931 commit 985c4af
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ public List<ModerationRequest> getRequestsByRequestingUser(User user) throws TEx
return handler.getRequestsByRequestingUser(user.getEmail());
}

@Override
public List<ModerationRequest> getRequestsByRequestingUserWithPagination(User user, PaginationData pageData) throws TException {
assertUser(user);

return handler.getRequestsByRequestingUserWithPagination(user.getEmail(), pageData);
}

@Override
public ClearingRequest getClearingRequestByProjectId(String projectId, User user) throws TException {
assertId(projectId);
Expand Down Expand Up @@ -372,6 +379,12 @@ public Map<String, Long> getCountByModerationState(User user) throws TException
return handler.getCountByModerationState(user.getEmail());
}

@Override
public Map<String, Long> getCountByRequester(User user) throws TException {
assertUser(user);
return handler.getCountByRequester(user.getEmail());
}

@Override
public Map<PaginationData, List<ModerationRequest>> getRequestsByModeratorWithPagination(User user,
PaginationData pageData, boolean open) throws TException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ public List<ModerationRequest> getRequestsByRequestingUser(String user) {
return repository.getRequestsByRequestingUser(user);
}

public List<ModerationRequest> getRequestsByRequestingUserWithPagination(String user, PaginationData pageData) {
return repository.getRequestsByRequestingUserWithPagination(user, pageData);
}

public ClearingRequest getClearingRequestByProjectId(String projectId, User user) throws SW360Exception {
projectDatabaseHandler.getProjectById(projectId, user); // check if user have READ access to project.
return clearingRequestRepository.getClearingRequestByProjectId(projectId);
Expand Down Expand Up @@ -890,6 +894,10 @@ public Map<String, Long> getCountByModerationState(String moderator) {
return repository.getCountByModerationState(moderator);
}

public Map<String, Long> getCountByRequester(String moderator) {
return repository.getCountByRequester(moderator);
}

public Set<String> getRequestingUserDepts() {
return repository.getRequestingUserDepts();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,19 @@ public class ModerationRequestRepository extends SummaryAwareRepository<Moderati
" }" +
"}";

private static final String COUNTBYREQUESTER = "function(doc) {" +
" if (doc.type == 'moderation') {" +
" emit([doc.requestingUser], null);" +
" }" +
"}";

public ModerationRequestRepository(DatabaseConnectorCloudant db) {
super(ModerationRequest.class, db, new ModerationRequestSummary());
Map<String, MapReduce> views = new HashMap<String, MapReduce>();
views.put("all", createMapReduce(ALL, null));
views.put("byRequestingUsersDeptView", createMapReduce(REQUESTING_USERS_VIEW, null));
views.put("countByModerationState", createMapReduce(COUNTBYMODERATIONSTATE, "_count"));
views.put("countByRequester", createMapReduce(COUNTBYREQUESTER, "_count"));
initStandardDesignDocument(views, db);
createIndex("byModerators", new String[] {"moderators"}, db);
createIndex("byDate", new String[] {"timestamp"}, db);
Expand Down Expand Up @@ -260,6 +267,29 @@ public List<ModerationRequest> getRequestsByRequestingUser(String user) {
return makeSummaryFromFullDocs(SummaryType.SHORT, mrs);
}

public List<ModerationRequest> getRequestsByRequestingUserWithPagination(String user, PaginationData pageData) {
final int rowsPerPage = pageData.getRowsPerPage();
final boolean ascending = pageData.isAscending();
final int skip = pageData.getDisplayStart();
final Selector typeSelector = eq("type", "moderation");
final Selector filterByModeratorSelector = eq("requestingUser", user);
final Selector finalSelector = and(typeSelector, filterByModeratorSelector);
QueryBuilder qb = new QueryBuilder(finalSelector);
qb.limit(rowsPerPage);
qb.skip(skip);
qb.useIndex("byUsers");
qb = ascending ? qb.sort(Sort.asc("timestamp")) : qb.sort(Sort.desc("timestamp"));

List<ModerationRequest> modReqs = Lists.newArrayList();
try {
QueryResult<ModerationRequest> queryResult = getConnector().getQueryResult(qb.build(), ModerationRequest.class);
modReqs = queryResult.getDocs();
} catch (Exception e) {
log.error("Error getting moderation requests", e);
}
return modReqs;
}

public Map<String, Long> getCountByModerationState(String moderator) {
Map<String, Long> countByModerationState = Maps.newHashMap();
List<ComplexKey> keys = prepareKeys(moderator, true);
Expand All @@ -282,6 +312,27 @@ public Map<String, Long> getCountByModerationState(String moderator) {
return countByModerationState;
}

public Map<String, Long> getCountByRequester(String user) {
Map<String, Long> countByModerationState = Maps.newHashMap();

List<ComplexKey> keys = prepareKeys(user, true);
ViewRequest<ComplexKey, Long> countReq = getConnector()
.createQuery(ModerationRequest.class, "countByRequester").newRequest(Key.Type.COMPLEX, Long.class)
.startKey(keys.get(0)).endKey(keys.get(1)).group(true).groupLevel(2).reduce(true).build();
try {
ViewResponse<ComplexKey, Long> response = countReq.getResponse();
if (null != response) {
countByModerationState = response.getRows().stream().collect(Collectors.toMap(key -> {
String json = key.getKey().toJson();
return json.replaceAll("[\\[\\]\"]", "");
}, ViewResponse.Row::getValue));
}
} catch (IOException e) {
log.error("Error getting count of moderation requests based on moderation state", e);
}
return countByModerationState;
}

public Set<String> getRequestingUserDepts() {
Set<String> requestingUserDepts = Sets.newHashSet();
ViewRequest<String, Object> query = getConnector()
Expand Down
10 changes: 10 additions & 0 deletions libraries/datahandler/src/main/thrift/moderation.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ service ModerationService {
**/
list<ModerationRequest> getRequestsByRequestingUser(1: User user);

/**
* get list of moderation requests where user is requesting user, paginated
**/
list<ModerationRequest> getRequestsByRequestingUserWithPagination(1: User user, 2: PaginationData pageData);

/**
* delete moderation request specified by id if user is requesting user of moderation request
**/
Expand Down Expand Up @@ -334,6 +339,11 @@ service ModerationService {
**/
map<string, i64> getCountByModerationState(1: User user);

/**
* get count of moderation requests by a requester
**/
map<string, i64> getCountByRequester(1: User user);

/**
* get requesting users departments
**/
Expand Down
14 changes: 14 additions & 0 deletions rest/resource-server/src/docs/asciidoc/moderationRequests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,17 @@ include::{snippets}/should_document_get_moderationrequests_assign/curl-request.a

===== Example response
include::{snippets}/should_document_get_moderationrequests_assign/http-response.adoc[]

[[resources-moderationRequest-submission]]
==== Get Submitted Moderation Requests

A `GET` will pull <<resources-moderationRequest, ModerationRequest>> which are created by the requesting user.

===== Response structure
include::{snippets}/should_document_get_moderationrequests_submission/response-fields.adoc[]

===== Example request
include::{snippets}/should_document_get_moderationrequests_submission/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_get_moderationrequests_submission/http-response.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,14 @@ public ResponseEntity<CollectionModel<ModerationRequest>> getModerationRequests(
) throws TException, ResourceClassNotFoundException, URISyntaxException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
List<ModerationRequest> moderationRequests = sw360ModerationRequestService.getRequestsByModerator(sw360User, pageable);
int totalCount = (int) sw360ModerationRequestService.getTotalCountOfRequests(sw360User);
PaginationResult<ModerationRequest> paginationResult = restControllerHelper.paginationResultFromPaginatedList(request,
pageable, moderationRequests, SW360Constants.TYPE_MODERATION, totalCount);

List<EntityModel<ModerationRequest>> moderationRequestResources = new ArrayList<>();
paginationResult.getResources().forEach(m -> addModerationRequest(m, allDetails, moderationRequestResources));

CollectionModel<ModerationRequest> resources;
if (moderationRequestResources.isEmpty()) {
resources = restControllerHelper.emptyPageResource(ModerationRequest.class, paginationResult);
} else {
resources = restControllerHelper.generatePagesResource(paginationResult, moderationRequestResources);
}
Map<PaginationData, List<ModerationRequest>> modRequestsWithPageData =
new HashMap<>();
PaginationData paginationData = new PaginationData();
paginationData.setTotalRowCount(sw360ModerationRequestService.getTotalCountOfRequests(sw360User));
modRequestsWithPageData.put(paginationData, moderationRequests);

HttpStatus status = resources == null ? HttpStatus.NO_CONTENT : HttpStatus.OK;
return new ResponseEntity<>(resources, status);
return getModerationResponseEntity(pageable, request, allDetails, modRequestsWithPageData);
}

@Operation(
Expand Down Expand Up @@ -166,27 +158,7 @@ public ResponseEntity<CollectionModel<ModerationRequest>> getModerationRequestsB
boolean stateOpen = stateOptions.get(0).equalsIgnoreCase(state);
Map<PaginationData, List<ModerationRequest>> modRequestsWithPageData =
sw360ModerationRequestService.getRequestsByState(sw360User, pageable, stateOpen, allDetails);
List<ModerationRequest> moderationRequests = new ArrayList<>();
int totalCount = 0;
if (!CommonUtils.isNullOrEmptyMap(modRequestsWithPageData)) {
PaginationData paginationData = modRequestsWithPageData.keySet().iterator().next();
moderationRequests = modRequestsWithPageData.get(paginationData);
totalCount = (int) paginationData.getTotalRowCount();
}

PaginationResult<ModerationRequest> paginationResult = restControllerHelper.paginationResultFromPaginatedList(request,
pageable, moderationRequests, SW360Constants.TYPE_MODERATION, totalCount);

List<EntityModel<ModerationRequest>> moderationRequestResources = new ArrayList<>();
paginationResult.getResources().forEach(m -> addModerationRequest(m, allDetails, moderationRequestResources));

CollectionModel<ModerationRequest> resources;
if (moderationRequestResources.isEmpty()) {
resources = restControllerHelper.emptyPageResource(ModerationRequest.class, paginationResult);
} else {
resources = restControllerHelper.generatePagesResource(paginationResult, moderationRequestResources);
}
return new ResponseEntity<>(resources, HttpStatus.OK);
return getModerationResponseEntity(pageable, request, allDetails, modRequestsWithPageData);
}

private @NotNull HalResource<ModerationRequest> createHalModerationRequestWithAllDetails(
Expand Down Expand Up @@ -317,4 +289,56 @@ private void addModerationRequest(ModerationRequest moderationRequest, boolean a
}
moderationRequestResources.add(embeddedModerationRequestResource);
}

@Operation(
summary = "Get my submissions.",
description = "Get moderation requests submitted by the user.",
tags = {"Moderation Requests"}
)
@GetMapping(value = MODERATION_REQUEST_URL + "/mySubmissions")
public ResponseEntity<CollectionModel<ModerationRequest>> getSubmissions(
Pageable pageable, HttpServletRequest request
) throws TException, URISyntaxException, ResourceClassNotFoundException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
Map<PaginationData, List<ModerationRequest>> modRequestsWithPageData =
sw360ModerationRequestService.getRequestsByRequestingUser(sw360User, pageable);
return getModerationResponseEntity(pageable, request, false, modRequestsWithPageData);
}

/**
* Generate a Response Entity for paginated moderation request list.
* @param pageable Pageable request
* @param request HTTP Request
* @param allDetails Request with allDetails?
* @param modRequestsWithPageData Map of pagination data and moderation request list
* @return Returns the Response Entity with pagination data.
*/
@NotNull
private ResponseEntity<CollectionModel<ModerationRequest>> getModerationResponseEntity(
Pageable pageable, HttpServletRequest request, boolean allDetails,
Map<PaginationData, List<ModerationRequest>> modRequestsWithPageData
) throws ResourceClassNotFoundException, URISyntaxException {
List<ModerationRequest> moderationRequests = new ArrayList<>();
int totalCount = 0;
if (!CommonUtils.isNullOrEmptyMap(modRequestsWithPageData)) {
PaginationData paginationData = modRequestsWithPageData.keySet().iterator().next();
moderationRequests = modRequestsWithPageData.get(paginationData);
totalCount = (int) paginationData.getTotalRowCount();
}

PaginationResult<ModerationRequest> paginationResult = restControllerHelper.paginationResultFromPaginatedList(
request, pageable, moderationRequests, SW360Constants.TYPE_MODERATION, totalCount);

List<EntityModel<ModerationRequest>> moderationRequestResources = new ArrayList<>();
paginationResult.getResources().forEach(m -> addModerationRequest(m, allDetails, moderationRequestResources));

CollectionModel<ModerationRequest> resources;
if (moderationRequestResources.isEmpty()) {
resources = restControllerHelper.emptyPageResource(ModerationRequest.class, paginationResult);
} else {
resources = restControllerHelper.generatePagesResource(paginationResult, moderationRequestResources);
}
HttpStatus status = resources == null ? HttpStatus.NO_CONTENT : HttpStatus.OK;
return new ResponseEntity<>(resources, status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.springframework.stereotype.Service;

import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -94,6 +95,29 @@ public List<ModerationRequest> getRequestsByModerator(User sw360User, Pageable p
return getThriftModerationClient().getRequestsByModeratorWithPaginationNoFilter(sw360User, pageData);
}

/**
* Get paginated list of moderation requests where user is the requester.
* @param sw360User Requester
* @param pageable Pageable information from request
* @return Paginated list of moderation requests.
* @throws TException Exception in case of error.
*/
public Map<PaginationData, List<ModerationRequest>> getRequestsByRequestingUser(
User sw360User, Pageable pageable
) throws TException {
PaginationData pageData = pageableToPaginationData(pageable);
ModerationService.Iface client = getThriftModerationClient();

List<ModerationRequest> moderationList = client.
getRequestsByRequestingUserWithPagination(sw360User, pageData);
Map<String, Long> countInfo = client.getCountByRequester(sw360User);
pageData.setTotalRowCount(countInfo.getOrDefault(sw360User.getEmail(), 0L));

Map<PaginationData, List<ModerationRequest>> result = new HashMap<>();
result.put(pageData, moderationList);
return result;
}

/**
* Get total count of moderation requests with user as a moderator.
*
Expand Down
Loading

0 comments on commit 985c4af

Please sign in to comment.