Skip to content

Commit

Permalink
[SELC-4840] feat: added ivass client and ivass connector in rest conn…
Browse files Browse the repository at this point in the history
…ectors (#221)
  • Loading branch information
empassaro authored Aug 27, 2024
1 parent b8aaf56 commit 9012e3b
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import it.pagopa.selfcare.party.registry_proxy.connector.model.ResourceResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
Expand All @@ -24,6 +25,10 @@
@Service
@Slf4j
@PropertySource("classpath:config/ivass-config.properties")
@ConditionalOnProperty(
value = "ivass.file.connector.type",
havingValue = "azure",
matchIfMissing = true)
public class IvassDataConnectorImpl implements IvassDataConnector {

private final FileStorageConnector fileStorageConnector;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package it.pagopa.selfcare.party.registry_proxy.connector.rest;

import it.pagopa.selfcare.party.registry_proxy.connector.api.IvassDataConnector;
import it.pagopa.selfcare.party.registry_proxy.connector.model.InsuranceCompany;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.client.IvassRestClient;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.utils.IvassUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@PropertySource("classpath:config/ivass-rest-config.properties")
@ConditionalOnProperty(
value = "ivass.file.connector.type",
havingValue = "rest")
public class IvassConnectorImpl implements IvassDataConnector {
private final IvassRestClient ivassRestClient;
private final List<String> registryTypesAdmitted;
private final List<String> workTypesAdmitted;
private final IvassUtils ivassUtils;

public IvassConnectorImpl(
IvassRestClient ivassRestClient,
@Value("#{'${ivass.registryTypes.admitted}'.split(',')}") List<String> registryTypes,
@Value("#{'${ivass.workTypes.admitted}'.split(',')}") List<String> registryWorkTypes,
IvassUtils ivassUtils
) {
this.ivassRestClient = ivassRestClient;
this.registryTypesAdmitted = registryTypes;
this.workTypesAdmitted = registryWorkTypes;
this.ivassUtils = ivassUtils;
}

@Override
public List<InsuranceCompany> getInsurances() {
byte[] zip = ivassRestClient.getInsurancesZip();
byte[] csv = ivassUtils.extractFirstEntryByteArrayFromZip(zip);
csv = ivassUtils.manageUTF8BOM(csv);
List<InsuranceCompany> companies = ivassUtils.readCsv(csv);
return filterCompanies(companies);
}

private List<InsuranceCompany> filterCompanies(List<InsuranceCompany> companies) {
return companies
.stream()
.filter(company -> StringUtils.hasText(company.getDigitalAddress())
&& workTypesAdmitted.contains(company.getWorkType())
&& registryTypesAdmitted
.stream()
.anyMatch(StringUtils.trimAllWhitespace(company.getRegisterType()
.split("-")[0])::equals))
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package it.pagopa.selfcare.party.registry_proxy.connector.rest.client;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Slf4j
@Component
@PropertySource("classpath:config/ivass-rest-config.properties")
public class IvassRestClient {
private final RestTemplate ivassRestTemplate;
private final String ivassBasePath;
private final String getInsurancesPath;

public IvassRestClient(
@Value("${ivass.rest.endpoint}") String ivassBasePath,
@Value("${ivass.rest.getInsurances.path}") String getInsurancesPath,
RestTemplate ivassRestTemplate) {
this.ivassRestTemplate = ivassRestTemplate;
this.ivassBasePath = ivassBasePath;
this.getInsurancesPath = getInsurancesPath;
}

public byte[] getInsurancesZip() {
log.info("getInsurances start");
String apiPath = this.ivassBasePath + getInsurancesPath;
return ivassRestTemplate.getForObject(apiPath, byte[].class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package it.pagopa.selfcare.party.registry_proxy.connector.rest.config;

import it.pagopa.selfcare.party.registry_proxy.connector.rest.decoder.RestTemplateErrorHandler;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.interceptor.IvassInterceptor;
import org.apache.http.client.CookieStore;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Configuration
public class RestTemplateConfig {
private final IvassInterceptor ivassInterceptor;
private final RestTemplateErrorHandler restTemplateErrorHandler;

public RestTemplateConfig(IvassInterceptor ivassInterceptor, RestTemplateErrorHandler restTemplateErrorHandler) {
this.ivassInterceptor = ivassInterceptor;
this.restTemplateErrorHandler = restTemplateErrorHandler;
}

@Bean
public RestTemplate ivassRestTemplate() {
CookieStore cookieStore = new BasicCookieStore();

CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.setRedirectStrategy(new LaxRedirectStrategy())
.build();

HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);

RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setInterceptors(List.of(ivassInterceptor));
restTemplate.setErrorHandler(restTemplateErrorHandler);
return restTemplate;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ivass.rest.endpoint=${IVASS_BASE_URL:http://localhost:8085}
ivass.rest.getInsurances.path=/RIGAInquiry-public/getAreaDownloadExport.do?referenceDate=&product=VFLUSSO_IMPRESE&language=IT&exportType=CSV&isCompressed=S
ivass.registryTypes.admitted=${IVASS_REGISTRY_TYPES:ElencoI,ElencoII,SezioneI,SezioneII}
ivass.workTypes.admitted=${IVASS_WORK_TYPES:VITA,PICCOLO CUMULO,MISTA}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package it.pagopa.selfcare.party.registry_proxy.connector.rest;

import it.pagopa.selfcare.party.registry_proxy.connector.model.InsuranceCompany;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.client.IvassRestClient;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.model.IvassDataTemplate;
import it.pagopa.selfcare.party.registry_proxy.connector.rest.utils.IvassUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

class IvassConnectorImplTest {
private IvassRestClient ivassRestClient;
private IvassUtils ivassUtils;
private IvassConnectorImpl ivassConnector;

@BeforeEach
void setUp() {
this.ivassRestClient = mock(IvassRestClient.class);
this.ivassUtils = mock(IvassUtils.class);
List<String> registryTypes = Arrays.asList("ElencoI","ElencoII","SezioneI","SezioneII");
List<String> workTypes = Arrays.asList("VITA","PICCOLO CUMULO","MISTA");
ivassConnector = new IvassConnectorImpl(ivassRestClient, registryTypes, workTypes, ivassUtils);
}

@Test
void getInsurances_shouldReturnFilteredCompanies() {
byte[] zip = new byte[]{0, 1, 2, 3, 4};
byte[] csv = new byte[]{5, 6, 7, 8, 9};

IvassDataTemplate company1 = new IvassDataTemplate();
company1.setDigitalAddress("digitalAddress1");
company1.setWorkType("VITA");
company1.setRegisterType("ElencoI - test");
company1.setTaxCode("taxCode1");

IvassDataTemplate company2 = new IvassDataTemplate();
company2.setDigitalAddress("digitalAddress2");
company2.setWorkType("VITA");
company2.setRegisterType("ElencoII - test");
company2.setTaxCode("taxCode2");


List<InsuranceCompany> companies = Arrays.asList(company1, company2);

when(ivassRestClient.getInsurancesZip()).thenReturn(zip);
when(ivassUtils.extractFirstEntryByteArrayFromZip(zip)).thenReturn(csv);
when(ivassUtils.readCsv(csv)).thenReturn(companies);
when(ivassUtils.manageUTF8BOM(csv)).thenReturn(csv);

List<InsuranceCompany> result = ivassConnector.getInsurances();

assertEquals(companies.size(), result.size());
verify(ivassRestClient, times(1)).getInsurancesZip();
verify(ivassUtils, times(1)).extractFirstEntryByteArrayFromZip(zip);
}

@Test
void getInsurances_shouldReturnEmptyList_whenNoCompaniesMatchFilter() {
byte[] zip = new byte[]{0, 1, 2, 3, 4};
byte[] csv = new byte[]{5, 6, 7, 8, 9};
List<InsuranceCompany> companies = Arrays.asList(new IvassDataTemplate(), new IvassDataTemplate());

when(ivassRestClient.getInsurancesZip()).thenReturn(zip);
when(ivassUtils.extractFirstEntryByteArrayFromZip(zip)).thenReturn(csv);
when(ivassUtils.readCsv(csv)).thenReturn(companies);

ivassConnector = spy(ivassConnector);

List<InsuranceCompany> result = ivassConnector.getInsurances();

assertEquals(0, result.size());
verify(ivassRestClient, times(1)).getInsurancesZip();
verify(ivassUtils, times(1)).extractFirstEntryByteArrayFromZip(zip);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package it.pagopa.selfcare.party.registry_proxy.connector.rest.client;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.web.client.RestTemplate;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;

class IvassRestClientTest {

@Mock
private RestTemplate restTemplate;

@InjectMocks
private IvassRestClient ivassRestClient;

@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
ivassRestClient = new IvassRestClient("http://example.com", "getInsurancesPath", restTemplate);
}

@Test
void getInsurancesZip_shouldReturnByteArray_whenSuccessful() {
byte[] expectedResponse = new byte[]{1, 2, 3};
when(restTemplate.getForObject(anyString(), eq(byte[].class))).thenReturn(expectedResponse);

byte[] result = ivassRestClient.getInsurancesZip();

assertArrayEquals(expectedResponse, result);
verify(restTemplate, times(1)).getForObject(anyString(), eq(byte[].class));
}

@Test
void getInsurancesZip_shouldThrowException_whenRestTemplateThrowsException() {
when(restTemplate.getForObject(anyString(), eq(byte[].class))).thenThrow(new RuntimeException("Test exception"));

assertThrows(RuntimeException.class, () -> ivassRestClient.getInsurancesZip());
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package it.pagopa.selfcare.party.registry_proxy.core;

import it.pagopa.selfcare.party.registry_proxy.connector.api.IndexSearchService;
import it.pagopa.selfcare.party.registry_proxy.connector.api.IndexWriterService;
import it.pagopa.selfcare.party.registry_proxy.connector.api.IvassDataConnector;
import it.pagopa.selfcare.party.registry_proxy.connector.exception.ResourceNotFoundException;
import it.pagopa.selfcare.party.registry_proxy.connector.model.Entity;
import it.pagopa.selfcare.party.registry_proxy.connector.model.InsuranceCompany;
import it.pagopa.selfcare.party.registry_proxy.connector.model.QueryResult;
import it.pagopa.selfcare.party.registry_proxy.core.exception.TooManyResourceFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -18,11 +21,19 @@
public class IvassServiceImpl implements IvassService {

private final IndexSearchService<InsuranceCompany> indexSearchService;
private final IvassDataConnector ivassDataConnector;
private final IndexWriterService<InsuranceCompany> indexWriterService;

@Autowired
IvassServiceImpl(IndexSearchService<InsuranceCompany> indexSearchService) {
IvassServiceImpl(
IndexSearchService<InsuranceCompany> indexSearchService,
IndexWriterService<InsuranceCompany> indexWriterService,
IvassDataConnector ivassDataConnector
) {
log.trace("Initializing {}", IvassServiceImpl.class.getSimpleName());
this.indexSearchService = indexSearchService;
this.indexWriterService = indexWriterService;
this.ivassDataConnector = ivassDataConnector;
}

/**
Expand Down Expand Up @@ -71,4 +82,14 @@ public QueryResult<InsuranceCompany> search(Optional<String> searchText, int pag
return queryResult;
}

@Scheduled(cron = "0 0 0/6 * * *")
void updateIvassIndex() {
log.trace("start update IVASS Stations index");
List<InsuranceCompany> companies = ivassDataConnector.getInsurances();
if (!companies.isEmpty()) {
indexWriterService.cleanIndex(Entity.INSURANCE_COMPANY.toString());
indexWriterService.adds(companies);
}
log.trace("updated IVASS Stations index end");
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package it.pagopa.selfcare.party.registry_proxy.core;

import it.pagopa.selfcare.party.registry_proxy.connector.api.IndexSearchService;
import it.pagopa.selfcare.party.registry_proxy.connector.api.IndexWriterService;
import it.pagopa.selfcare.party.registry_proxy.connector.api.IvassDataConnector;
import it.pagopa.selfcare.party.registry_proxy.connector.exception.ResourceNotFoundException;
import it.pagopa.selfcare.party.registry_proxy.connector.model.*;
import it.pagopa.selfcare.party.registry_proxy.core.exception.TooManyResourceFoundException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.function.Executable;
Expand All @@ -23,7 +26,10 @@ class IvassServiceImplTest {

@Mock
private IndexSearchService<InsuranceCompany> indexSearchService;

@Mock
private IvassDataConnector ivassDataConnector;
@Mock
private IndexWriterService<InsuranceCompany> indexWriterService;
@InjectMocks
private IvassServiceImpl ivassService;

Expand Down Expand Up @@ -144,4 +150,12 @@ void search_notEmptySearchText() {
.fullTextSearch(InsuranceCompany.Field.DESCRIPTION, searchText.get(), page, limit);
verifyNoMoreInteractions(indexSearchService);
}

@Test
void updateIvassIndex() {
List<InsuranceCompany> companies = List.of(new DummyInsuranceCompany());
when(ivassDataConnector.getInsurances()).thenReturn(companies);
Executable executable = () -> ivassService.updateIvassIndex();
Assertions.assertDoesNotThrow(executable);
}
}

0 comments on commit 9012e3b

Please sign in to comment.