Pull request #157: RED-3011 - DossierTemplate Stats

Merge in RED/persistence-service from feature/RED-3011 to master

* commit 'cc29d967a39a8b7e535774631ea4563f8c84f186':
  RED-3011 - DossierTemplate Stats
This commit is contained in:
Corina Olariu 2021-12-13 14:58:06 +01:00 committed by Timo Bejan
commit 8c4be5780e
10 changed files with 296 additions and 0 deletions

View File

@ -0,0 +1,20 @@
package com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummary;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DossierTemplateStats {
private String dossierTemplateId;
private int numberOfDictionaries; // number of Types for the dossierTemplate
private List<DictionarySummary> dictionarySummaryList = new ArrayList<>();
}

View File

@ -0,0 +1,17 @@
package com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DictionarySummary {
private String id; // type id
private String type; // type
private String name; // label
private long entriesCount; // entries size
}

View File

@ -0,0 +1,19 @@
package com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DictionarySummaryResponse {
private String dossierTemplateId;
private String id; // type id
private String type; // type
private String name; // label
private long entriesCount; // entries size
}

View File

@ -0,0 +1,17 @@
package com.iqser.red.service.persistence.service.v1.api.resources;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierTemplateStats;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
import java.util.Set;
public interface DossierTemplateStatsResource {
String REST_PATH = "/dossier-template-stats";
@PostMapping(value = REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
List<DossierTemplateStats> getDossierTemplateStats(@RequestBody Set<String> dossierTemplateIds);
}

View File

@ -6,6 +6,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.NotFo
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummaryResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@ -13,6 +14,7 @@ import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId;
@ -119,5 +121,9 @@ public class DictionaryPersistenceService {
return typeRepository.getVersionForDossierId(dossierId);
}
public List<DictionarySummaryResponse> getDictionarySummaryForDossierTemplateId(Set<String> dossierTemplateIds) {
return typeRepository.findDictionarySummaryList(dossierTemplateIds);
}
}

View File

@ -3,12 +3,14 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummaryResponse;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface TypeRepository extends JpaRepository<TypeEntity, String> {
@ -35,4 +37,10 @@ public interface TypeRepository extends JpaRepository<TypeEntity, String> {
@Query("select coalesce(sum(t.version),0) from TypeEntity t where t.dossierTemplateId = :dossierTemplateId and t.dossierId is null")
long getVersionForDossierTemplateId(String dossierTemplateId);
@Query("select new com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummaryResponse(t.dossierTemplateId, t.id, t.type, t.label, count(e)) " +
"from TypeEntity t left join DictionaryEntryEntity e on e.type.id = t.id " +
"group by t.dossierTemplateId, t.id, t.type, t.label having t.dossierTemplateId in :dossierTemplateIds")
List<DictionarySummaryResponse> findDictionarySummaryList(Set<String> dossierTemplateIds);
}

View File

@ -0,0 +1,23 @@
package com.iqser.red.service.peristence.v1.server.controller;
import com.iqser.red.service.peristence.v1.server.service.DossierTemplateStatsService;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierTemplateStats;
import com.iqser.red.service.persistence.service.v1.api.resources.DossierTemplateStatsResource;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Set;
@RestController
@RequiredArgsConstructor
public class DossierTemplateStatsController implements DossierTemplateStatsResource {
private final DossierTemplateStatsService dossierTemplateStatsService;
@Override
public List<DossierTemplateStats> getDossierTemplateStats(@RequestBody Set<String> dossierTemplateIds) {
return dossierTemplateStatsService.getDossierTemplateStats(dossierTemplateIds);
}
}

View File

@ -0,0 +1,42 @@
package com.iqser.red.service.peristence.v1.server.service;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierTemplateStats;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummary;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummaryResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class DossierTemplateStatsService {
private final DictionaryPersistenceService dictionaryPersistenceService;
private final DossierTemplatePersistenceService dossierTemplatePersistenceService;
public List<DossierTemplateStats> getDossierTemplateStats(Set<String> dossierTemplateIds) {
List<DictionarySummaryResponse> dictionarySummaryList = dictionaryPersistenceService.getDictionarySummaryForDossierTemplateId(dossierTemplateIds);
Map<String, List<DictionarySummary>> dictionarySummaryMap = dictionarySummaryList.stream().collect(
Collectors.groupingBy(DictionarySummaryResponse::getDossierTemplateId,
Collectors.mapping(this::getDossierTemplateStats, Collectors.toList())));
List<DossierTemplateStats> dossierTemplateStatsList = dictionarySummaryMap.entrySet().stream()
.map(e ->
new DossierTemplateStats(e.getKey(), e.getValue().size(), e.getValue()))
.collect(Collectors.toList());
return dossierTemplateStatsList;
}
private DictionarySummary getDossierTemplateStats(DictionarySummaryResponse response) {
return new DictionarySummary(response.getId(), response.getType(), response.getName(), response.getEntriesCount());
}
}

View File

@ -0,0 +1,8 @@
package com.iqser.red.service.peristence.v1.server.integration.client;
import com.iqser.red.service.persistence.service.v1.api.resources.DossierTemplateStatsResource;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(name = "DossierTemplateStats", url = "http://localhost:${server.port}")
public interface DossierTemplateStatsClient extends DossierTemplateStatsResource {
}

View File

@ -0,0 +1,136 @@
package com.iqser.red.service.peristence.v1.server.integration.tests;
import com.google.common.collect.Sets;
import com.iqser.red.service.peristence.v1.server.integration.client.DictionaryClient;
import com.iqser.red.service.peristence.v1.server.integration.client.DossierTemplateClient;
import com.iqser.red.service.peristence.v1.server.integration.client.DossierTemplateStatsClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.CreateOrUpdateDossierTemplateRequest;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierTemplate;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierTemplateStats;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DownloadFileType;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionaryEntry;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.DictionarySummary;
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.Type;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
public class DossierTemplateStatsTest extends AbstractPersistenceServerServiceTest {
private static final String TYPE_ID_1 = "type1";
private static final String TYPE_ID_2 = "type2";
private static final String TYPE_ID_3 = "type3";
@Autowired
private DossierTesterAndProvider dossierTesterAndProvider;
@Autowired
private DictionaryClient dictionaryClient;
@Autowired
private DossierTemplateClient dossierTemplateClient;
@Autowired
private DossierTemplateStatsClient dossierTemplateStatsClient;
@Test
public void testDossierTemplateStats() {
var dossier = dossierTesterAndProvider.provideTestDossier();
var addedType = dictionaryClient.addType(Type.builder()
.type(TYPE_ID_1)
.label("Dossier Redactions")
.hexColor("#fcba03")
.rank(100)
.description("Something")
.addToDictionaryAction(false)
.dossierTemplateId(dossier.getDossierTemplateId())
.dossierId(null)
.build());
assertThat(addedType).isNotNull();
var entries1 = new ArrayList<String>();
entries1.add("entry1");
entries1.add("entry2");
dictionaryClient.addEntries(addedType.getTypeId(), entries1, false);
List<DictionaryEntry> entryList = dictionaryClient.getEntriesForType(addedType.getTypeId());
assertThat(entryList.size()).isEqualTo(entries1.size());
var addedType2 = dictionaryClient.addType(Type.builder()
.type(TYPE_ID_2)
.label("Dossier Redactions 2")
.hexColor("#fcba03")
.rank(102)
.description("Something")
.addToDictionaryAction(false)
.dossierTemplateId(dossier.getDossierTemplateId())
.dossierId(null)
.build());
var entries2 = new ArrayList<String>();
entries2.add("entry1");
entries2.add("entry2");
entries2.add("entry3");
dictionaryClient.addEntries(addedType2.getTypeId(), entries2, false);
entryList = dictionaryClient.getEntriesForType(addedType2.getTypeId());
assertThat(entryList.size()).isEqualTo(entries2.size());
var dossierTemplate2 = provideTestTemplate("dossierTemp2");
var addedType3 = dictionaryClient.addType(Type.builder()
.type(TYPE_ID_3)
.label("Dossier Redactions 3")
.hexColor("#fcba03")
.rank(100)
.description("Something")
.addToDictionaryAction(false)
.dossierTemplateId(dossierTemplate2.getId())
.dossierId(null)
.build());
assertThat(addedType).isNotNull();
var entries3 = new ArrayList<String>();
entries3.add("entry1");
entries3.add("entry2");
dictionaryClient.addEntries(addedType3.getTypeId(), entries3, false);
entryList = dictionaryClient.getEntriesForType(addedType3.getTypeId());
assertThat(entryList.size()).isEqualTo(entries3.size());
Set<String> dossierTemplateIds = new HashSet<>();
dossierTemplateIds.add(dossier.getDossierTemplateId());
dossierTemplateIds.add(dossierTemplate2.getId());
List<DossierTemplateStats> dossierTemplateStatsList = dossierTemplateStatsClient.getDossierTemplateStats(dossierTemplateIds);
DossierTemplateStats dossierTemplateStats = dossierTemplateStatsList.stream().filter(d -> d.getDossierTemplateId().equals(dossier.getDossierTemplateId())).findAny().get();
assertThat(dossierTemplateStats.getDossierTemplateId()).isEqualTo(dossier.getDossierTemplateId());
assertThat(dossierTemplateStats.getNumberOfDictionaries()).isEqualTo(2);
List<DictionarySummary> dictionarySummaryList = dossierTemplateStats.getDictionarySummaryList();
assertThat(dictionarySummaryList.stream().filter(d -> d.getType().equals(TYPE_ID_1)).findAny().get().getEntriesCount()).isEqualTo(entries1.size());
assertThat(dictionarySummaryList.stream().filter(d -> d.getType().equals(TYPE_ID_2)).findAny().get().getEntriesCount()).isEqualTo(entries2.size());
}
public DossierTemplate provideTestTemplate(String dossierTemplateName) {
CreateOrUpdateDossierTemplateRequest cru = new CreateOrUpdateDossierTemplateRequest();
cru.setDownloadFileTypes(Sets.newHashSet(DownloadFileType.ORIGINAL));
cru.setName(dossierTemplateName);
cru.setDescription("Template 1");
cru.setRequestingUser("1");
cru.setValidFrom(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
cru.setValidTo(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
return dossierTemplateClient.createOrUpdateDossierTemplate(cru);
}
}