Skip to content

Commit

Permalink
MAT-6257: return smaller LibraryList object (#68)
Browse files Browse the repository at this point in the history
* MAT-6257: change return to LibraryList

* MAT-6257: move libraryListDto
  • Loading branch information
chubert-sb authored Apr 26, 2024
1 parent 6f3eaca commit 0c3cbcb
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package gov.cms.madie.cqllibraryservice.controllers;

import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;
import gov.cms.madie.cqllibraryservice.exceptions.InvalidIdException;
import gov.cms.madie.cqllibraryservice.exceptions.InvalidResourceStateException;
import gov.cms.madie.cqllibraryservice.repositories.LibrarySetRepository;
import gov.cms.madie.cqllibraryservice.services.ActionLogService;
import gov.cms.madie.cqllibraryservice.services.LibrarySetService;
import gov.cms.madie.cqllibraryservice.utils.AuthUtils;
Expand All @@ -21,7 +21,6 @@

import jakarta.servlet.http.HttpServletRequest;

import gov.cms.madie.models.library.LibrarySet;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -43,24 +42,17 @@ public class CqlLibraryController {
private final VersionService versionService;
private final CqlLibraryService cqlLibraryService;
private final LibrarySetService librarySetService;
private final LibrarySetRepository librarySetRepository;

@GetMapping
public ResponseEntity<List<CqlLibrary>> getCqlLibraries(
public ResponseEntity<List<LibraryListDTO>> getCqlLibraries(
Principal principal,
@RequestParam(required = false, defaultValue = "false", name = "currentUser")
boolean filterByCurrentUser) {
final String username = principal.getName();
List<CqlLibrary> cqlLibraries =
List<LibraryListDTO> cqlLibraries =
filterByCurrentUser
? cqlLibraryRepository.findAllLibrariesByUser(username)
: cqlLibraryRepository.findAll();
cqlLibraries.forEach(
l -> {
LibrarySet librarySet =
librarySetRepository.findByLibrarySetId(l.getLibrarySetId()).orElse(null);
l.setLibrarySet(librarySet);
});
: cqlLibraryRepository.findAllProjected();
return ResponseEntity.ok(cqlLibraries);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gov.cms.madie.cqllibraryservice.dto;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import gov.cms.madie.models.common.ModelType;
import gov.cms.madie.models.common.Version;
import gov.cms.madie.models.library.CqlLibrary;
import gov.cms.madie.models.library.LibrarySet;
import gov.cms.madie.models.utils.VersionJsonSerializer;
import gov.cms.madie.models.validators.EnumValidator;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Document
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class LibraryListDTO {

private String id;
private String librarySetId;

private String cqlLibraryName;

@NotBlank(message = "Model is required")
@EnumValidator(
enumClass = ModelType.class,
message = "Model must be one of the supported types in MADiE.",
groups = {CqlLibrary.ValidationOrder4.class})
private String model;

@JsonSerialize(using = VersionJsonSerializer.VersionSerializer.class)
@JsonDeserialize(using = VersionJsonSerializer.VersionDeserializer.class)
private Version version;

@DBRef private LibrarySet librarySet;

private boolean draft;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.cms.madie.cqllibraryservice.repositories;

import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;
import gov.cms.madie.models.common.Version;
import gov.cms.madie.models.library.CqlLibrary;

Expand Down Expand Up @@ -31,4 +32,13 @@ List<CqlLibrary> findAllByCqlLibraryNameAndDraftAndVersionAndModel(
"{'$sort': {'createdAt':1}}"
})
List<CqlLibrary> findByCqlLibrarySetId();

@Aggregation(
pipeline = {
"{'$lookup' : {from: 'librarySet',"
+ "localField: 'librarySetId',"
+ "foreignField: 'librarySetId',"
+ "as: 'librarySet'}}"
})
List<LibraryListDTO> findAllProjected();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package gov.cms.madie.cqllibraryservice.repositories;

import gov.cms.madie.models.library.CqlLibrary;
import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;

import java.util.List;

Expand All @@ -11,5 +11,5 @@ public interface LibraryAclRepository {
* @param userId- current user
* @return List of cqlLibraries
*/
List<CqlLibrary> findAllLibrariesByUser(String userId);
List<LibraryListDTO> findAllLibrariesByUser(String userId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.cms.madie.cqllibraryservice.repositories;

import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;
import gov.cms.madie.models.access.RoleEnum;
import gov.cms.madie.models.library.CqlLibrary;

Expand All @@ -12,8 +13,7 @@

import java.util.List;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.match;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

@Repository
public class LibraryAclRepositoryImpl implements LibraryAclRepository {
Expand All @@ -32,7 +32,7 @@ private LookupOperation getLookupOperation() {
}

@Override
public List<CqlLibrary> findAllLibrariesByUser(String userId) {
public List<LibraryListDTO> findAllLibrariesByUser(String userId) {
Criteria librarySetCriteria =
new Criteria()
.orOperator(
Expand All @@ -42,11 +42,12 @@ public List<CqlLibrary> findAllLibrariesByUser(String userId) {
.and("librarySet.acls.roles")
.in(RoleEnum.SHARED_WITH));
MatchOperation matchOperation = match(librarySetCriteria);
Aggregation libraryAggregation = newAggregation(getLookupOperation(), matchOperation);
Aggregation libraryAggregation =
newAggregation(getLookupOperation(), matchOperation, project(LibraryListDTO.class));

List<CqlLibrary> results =
List<LibraryListDTO> results =
mongoTemplate
.aggregate(libraryAggregation, CqlLibrary.class, CqlLibrary.class)
.aggregate(libraryAggregation, CqlLibrary.class, LibraryListDTO.class)
.getMappedResults();
return results;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;
import gov.cms.madie.cqllibraryservice.exceptions.DuplicateKeyException;
import gov.cms.madie.cqllibraryservice.exceptions.InvalidIdException;
import gov.cms.madie.cqllibraryservice.exceptions.InvalidResourceStateException;
Expand Down Expand Up @@ -72,26 +73,34 @@ class CqlLibraryControllerTest {
@Captor private ArgumentCaptor<String> targetIdArgumentCaptor;

private CqlLibrary cqlLibrary;
private LibraryListDTO libraryList;

@BeforeEach
public void setUp() {
cqlLibrary = new CqlLibrary();
cqlLibrary.setId("testCqlLibraryId");
cqlLibrary.setCqlLibraryName("testCqlLibraryName");
cqlLibrary.setLibrarySetId("testCqlLibrarySetId");
cqlLibrary =
CqlLibrary.builder()
.id("testCqlLibraryId")
.cqlLibraryName("testCqlLibraryName")
.librarySetId("testCqlLibrarySetId")
.build();

libraryList =
LibraryListDTO.builder()
.id("testCqlLibraryId")
.cqlLibraryName("testCqlLibraryName")
.librarySetId("testCqlLibrarySetId")
.build();
}

@Test
void getCqlLibrariesWithoutCurrentUserFilter() {
List<CqlLibrary> cqlLibraries = List.of(cqlLibrary);
when(cqlLibraryRepository.findAll()).thenReturn(cqlLibraries);
List<LibraryListDTO> cqlLibraries = List.of(libraryList);
when(cqlLibraryRepository.findAllProjected()).thenReturn(cqlLibraries);
Principal principal = mock(Principal.class);
when(principal.getName()).thenReturn("test.user");
when(librarySetRepository.findByLibrarySetId(anyString()))
.thenReturn(Optional.of(new LibrarySet()));
ResponseEntity<List<CqlLibrary>> response =
ResponseEntity<List<LibraryListDTO>> response =
cqlLibraryController.getCqlLibraries(principal, false);
verify(cqlLibraryRepository, times(1)).findAll();
verify(cqlLibraryRepository, times(1)).findAllProjected();
verifyNoMoreInteractions(cqlLibraryRepository);
assertNotNull(response.getBody());
assertNotNull(response.getBody().get(0));
Expand All @@ -100,14 +109,12 @@ void getCqlLibrariesWithoutCurrentUserFilter() {

@Test
void getCqlLibrariesWithCurrentUserFilter() {
List<CqlLibrary> cqlLibraries = List.of(cqlLibrary);
List<LibraryListDTO> cqlLibraries = List.of(libraryList);
when(cqlLibraryRepository.findAllLibrariesByUser(anyString())).thenReturn(cqlLibraries);
Principal principal = mock(Principal.class);
when(principal.getName()).thenReturn("test.user");
when(librarySetRepository.findByLibrarySetId(anyString()))
.thenReturn(Optional.of(new LibrarySet()));

ResponseEntity<List<CqlLibrary>> response =
ResponseEntity<List<LibraryListDTO>> response =
cqlLibraryController.getCqlLibraries(principal, true);
verify(cqlLibraryRepository, times(1)).findAllLibrariesByUser(eq("test.user"));
verifyNoMoreInteractions(cqlLibraryRepository);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package gov.cms.madie.cqllibraryservice.repositories;

import gov.cms.madie.cqllibraryservice.dto.LibraryListDTO;
import gov.cms.madie.models.common.Version;
import gov.cms.madie.models.library.CqlLibrary;
import gov.cms.madie.models.library.LibrarySet;
import org.bson.Document;

Expand Down Expand Up @@ -31,19 +31,18 @@ public class LibraryAclRepositoryImplTest {

@InjectMocks LibraryAclRepositoryImpl libraryAclRepository;

private CqlLibrary library1;
private CqlLibrary library2;
private CqlLibrary library3;
private CqlLibrary library4;
private CqlLibrary library5;
private LibraryListDTO library1;
private LibraryListDTO library2;
private LibraryListDTO library3;
private LibraryListDTO library4;
private LibraryListDTO library5;

@BeforeEach
void setup() {
LibrarySet librarySet1 = LibrarySet.builder().owner("p1").librarySetId("id-1").build();
LibrarySet librarySet2 = LibrarySet.builder().owner("p2").librarySetId("id-1").build();
library1 =
CqlLibrary.builder()
.createdBy("p1")
LibraryListDTO.builder()
.id("1")
.cqlLibraryName("test measure 1")
.librarySetId("1-1")
Expand All @@ -52,8 +51,7 @@ void setup() {
.draft(true)
.build();
library2 =
CqlLibrary.builder()
.createdBy("p1")
LibraryListDTO.builder()
.id("2")
.cqlLibraryName("test measure 2")
.librarySetId("2-2")
Expand All @@ -62,8 +60,7 @@ void setup() {
.draft(true)
.build();
library3 =
CqlLibrary.builder()
.createdBy("p1")
LibraryListDTO.builder()
.id("3")
.cqlLibraryName("library3")
.librarySetId("id-2")
Expand All @@ -72,8 +69,7 @@ void setup() {
.draft(false)
.build();
library4 =
CqlLibrary.builder()
.createdBy("p2")
LibraryListDTO.builder()
.id("4")
.cqlLibraryName("library4")
.librarySetId("id-2")
Expand All @@ -82,8 +78,7 @@ void setup() {
.draft(false)
.build();
library5 =
CqlLibrary.builder()
.createdBy("p2")
LibraryListDTO.builder()
.id("5")
.cqlLibraryName("library5")
.librarySetId("id-2")
Expand All @@ -105,10 +100,9 @@ public void testfindAllMyLibraries() {
new AggregationResults<>(List.of(library1, library2, library3), new Document());

when(mongoTemplate.aggregate(any(Aggregation.class), (Class<?>) any(), any()))
.thenReturn(allResults)
.thenReturn(allResults);

List<CqlLibrary> list = libraryAclRepository.findAllLibrariesByUser("p1");
List<LibraryListDTO> list = libraryAclRepository.findAllLibrariesByUser("p1");
assertEquals(list.size(), 3);
}
}

0 comments on commit 0c3cbcb

Please sign in to comment.