Skip to content

Commit 77f8409

Browse files
committed
Merge branch 'develop' into UPBE-602-be-creazione-api-download-report
# Conflicts: # src/main/java/it/gov/pagopa/idpay/transactions/controller/ReportController.java # src/main/java/it/gov/pagopa/idpay/transactions/controller/ReportControllerImpl.java # src/main/java/it/gov/pagopa/idpay/transactions/service/ReportService.java # src/main/java/it/gov/pagopa/idpay/transactions/service/ReportServiceImpl.java # src/test/java/it/gov/pagopa/idpay/transactions/service/ReportServiceImplTest.java
2 parents a5ddff0 + 3d5da12 commit 77f8409

File tree

16 files changed

+508
-5
lines changed

16 files changed

+508
-5
lines changed

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@
9191
<artifactId>janino</artifactId>
9292
</dependency>
9393

94+
<dependency>
95+
<groupId>com.azure.resourcemanager</groupId>
96+
<artifactId>azure-resourcemanager-datafactory</artifactId>
97+
<version>1.2.0</version>
98+
</dependency>
99+
<dependency>
100+
<groupId>com.azure</groupId>
101+
<artifactId>azure-identity</artifactId>
102+
</dependency>
103+
94104
<!--TEST-->
95105
<dependency>
96106
<groupId>org.springframework.boot</groupId>

src/main/java/it/gov/pagopa/idpay/transactions/controller/ReportController.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package it.gov.pagopa.idpay.transactions.controller;
22

3-
import it.gov.pagopa.idpay.transactions.dto.*;
3+
import it.gov.pagopa.idpay.transactions.dto.PatchReportRequest;
4+
import it.gov.pagopa.idpay.transactions.dto.ReportDTO;
5+
import it.gov.pagopa.idpay.transactions.dto.ReportListDTO;
6+
import it.gov.pagopa.idpay.transactions.dto.ReportRequest;
7+
import it.gov.pagopa.idpay.transactions.dto.report.Report2RunDto;
8+
import it.gov.pagopa.idpay.transactions.dto.report.ReportGenerateForce;
49
import jakarta.validation.Valid;
510
import org.springframework.data.domain.Pageable;
611
import org.springframework.data.web.PageableDefault;
712
import org.springframework.web.bind.annotation.*;
813
import reactor.core.publisher.Mono;
914

15+
import java.util.List;
16+
1017
@RequestMapping("/idpay/merchant/portal")
1118
public interface ReportController {
1219

@@ -32,6 +39,9 @@ Mono<ReportDTO> generateReport(@RequestHeader("x-merchant-id") String merchantId
3239
@PathVariable("initiativeId") String initiativeId,
3340
@RequestBody @Valid ReportRequest request);
3441

42+
@PostMapping("/reports/transaction/force")
43+
Mono<List<Report2RunDto>> forceGenerateReports(@RequestBody ReportGenerateForce reportGenerateForce);
44+
3545

3646
@PatchMapping("/initiatives/{initiativeId}/reports/{reportId}")
3747
Mono<ReportDTO> patchReport(@PathVariable("initiativeId") String initiativeId,

src/main/java/it/gov/pagopa/idpay/transactions/controller/ReportControllerImpl.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package it.gov.pagopa.idpay.transactions.controller;
22

3-
import it.gov.pagopa.idpay.transactions.dto.*;
3+
import it.gov.pagopa.idpay.transactions.dto.PatchReportRequest;
4+
import it.gov.pagopa.idpay.transactions.dto.ReportDTO;
5+
import it.gov.pagopa.idpay.transactions.dto.ReportListDTO;
6+
import it.gov.pagopa.idpay.transactions.dto.ReportRequest;
7+
import it.gov.pagopa.idpay.transactions.dto.report.Report2RunDto;
8+
import it.gov.pagopa.idpay.transactions.dto.report.ReportGenerateForce;
49
import it.gov.pagopa.idpay.transactions.service.ReportService;
510
import it.gov.pagopa.idpay.transactions.dto.mapper.ReportMapper;
611
import it.gov.pagopa.idpay.transactions.utils.Utilities;
@@ -9,6 +14,8 @@
914
import org.springframework.web.bind.annotation.RestController;
1015
import reactor.core.publisher.Mono;
1116

17+
import java.util.List;
18+
1219
@RestController
1320
@Slf4j
1421
public class ReportControllerImpl implements ReportController {
@@ -71,4 +78,9 @@ public Mono<ReportDTO> patchReport(String initiativeId,
7178
) {
7279
return reportService.patchReport(initiativeId, reportId, request);
7380
}
81+
82+
@Override
83+
public Mono<List<Report2RunDto>> forceGenerateReports(ReportGenerateForce reportGenerateForce) {
84+
return reportService.forceGenerateReports(reportGenerateForce);
85+
}
7486
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package it.gov.pagopa.idpay.transactions.data.factory;
2+
3+
import com.azure.core.management.AzureEnvironment;
4+
import com.azure.core.management.profile.AzureProfile;
5+
import com.azure.identity.DefaultAzureCredential;
6+
import com.azure.identity.DefaultAzureCredentialBuilder;
7+
import org.springframework.beans.factory.annotation.Value;
8+
import org.springframework.context.annotation.Bean;
9+
import org.springframework.context.annotation.Configuration;
10+
import com.azure.resourcemanager.datafactory.DataFactoryManager;
11+
12+
13+
@Configuration
14+
public class DataFactoryManagerConfig {
15+
private final String tenantId;
16+
private final String subscriptionId;
17+
18+
public DataFactoryManagerConfig(@Value("${app.data-factory.tenant-id}") String tenantId,
19+
@Value("${app.data-factory.subscription-id}") String subscriptionId) {
20+
this.tenantId = tenantId;
21+
this.subscriptionId = subscriptionId;
22+
}
23+
24+
@Bean
25+
public DataFactoryManager dataFactoryManager () {
26+
DefaultAzureCredential azureCredentials = new DefaultAzureCredentialBuilder().build();
27+
AzureProfile azureProfile = new AzureProfile(tenantId, subscriptionId, AzureEnvironment.AZURE);
28+
return DataFactoryManager.authenticate(azureCredentials, azureProfile);
29+
}
30+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package it.gov.pagopa.idpay.transactions.data.factory;
2+
3+
import it.gov.pagopa.idpay.transactions.model.Report;
4+
import reactor.core.publisher.Mono;
5+
6+
public interface DataFactoryService {
7+
Mono<String> triggerTransactionReportPipeline(Report report);
8+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package it.gov.pagopa.idpay.transactions.data.factory;
2+
3+
import com.azure.core.http.rest.Response;
4+
import com.azure.core.util.Context;
5+
import com.azure.resourcemanager.datafactory.models.CreateRunResponse;
6+
import it.gov.pagopa.idpay.transactions.exception.AzureConnectingErrorException;
7+
import it.gov.pagopa.idpay.transactions.model.Report;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.stereotype.Service;
11+
import com.azure.resourcemanager.datafactory.DataFactoryManager;
12+
import reactor.core.publisher.Mono;
13+
import reactor.core.scheduler.Schedulers;
14+
import reactor.util.retry.Retry;
15+
16+
import java.time.Duration;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
20+
@Service
21+
@Slf4j
22+
public class DataFactoryServiceImpl implements DataFactoryService{
23+
private final DataFactoryManager dataFactoryManager;
24+
private final String resourceGroup;
25+
private final String factoryName;
26+
private final String pipelineName;
27+
private final int maxRetries;
28+
29+
public DataFactoryServiceImpl(DataFactoryManager dataFactoryManager,
30+
@Value("${app.data-factory.resource-group}") String resourceGroup,
31+
@Value("${app.data-factory.factory-name}") String factoryName,
32+
@Value("${app.data-factory.pipeline-name}") String pipelineName,
33+
@Value("${app.data-factory.max-retries}") int maxRetries) {
34+
this.dataFactoryManager = dataFactoryManager;
35+
this.resourceGroup = resourceGroup;
36+
this.factoryName = factoryName;
37+
this.pipelineName = pipelineName;
38+
this.maxRetries = maxRetries;
39+
}
40+
41+
@Override
42+
public Mono<String> triggerTransactionReportPipeline(Report report) {
43+
Mono<String> callMono = Mono.fromCallable(() -> {
44+
log.info("[CALLING_DATA_FACTORY] Starting pipeline execution for Report {}", report.getId());
45+
Response<CreateRunResponse> resp = dataFactoryManager.pipelines().createRunWithResponse(
46+
resourceGroup,
47+
factoryName,
48+
pipelineName,
49+
null,
50+
false,
51+
null,
52+
false,
53+
createPipelineParameters(report),
54+
Context.NONE);
55+
56+
int status = resp.getStatusCode();
57+
if (status < 200 || status >= 300) {
58+
throw new IllegalStateException("ADF createRun failed. HTTP status: " + status);
59+
}
60+
61+
CreateRunResponse body = resp.getValue();
62+
if (body == null) {
63+
throw new IllegalStateException("ADF createRun returned empty body");
64+
}
65+
log.info("[CALLING_DATA_FACTORY] Report {} generation request sent successfully. Run ID: {}", report.getId(), body.runId());
66+
return body.runId();
67+
})
68+
.subscribeOn(Schedulers.boundedElastic());
69+
70+
return callMono
71+
.retryWhen(Retry.fixedDelay(maxRetries, Duration.ofSeconds(1))
72+
.onRetryExhaustedThrow((spec, signal) ->
73+
new AzureConnectingErrorException(
74+
"Failed to trigger ADF pipeline after " + (maxRetries + 1) + " attempts",
75+
signal.failure()
76+
)
77+
)
78+
);
79+
}
80+
81+
private Map<String, Object> createPipelineParameters(Report report) {
82+
HashMap<String, Object> parameters = new HashMap<>();
83+
parameters.put("reportId", report.getId());
84+
parameters.put("merchantId", report.getMerchantId());
85+
parameters.put("initiativeId", report.getInitiativeId());
86+
parameters.put("startDate", report.getStartPeriod());
87+
parameters.put("endDate", report.getEndPeriod());
88+
parameters.put("reportName", report.getFileName());
89+
90+
return parameters;
91+
}
92+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package it.gov.pagopa.idpay.transactions.dto.report;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
@Data
9+
@AllArgsConstructor
10+
@NoArgsConstructor
11+
@Builder
12+
public class Report2RunDto {
13+
String reportId;
14+
String runId;
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package it.gov.pagopa.idpay.transactions.dto.report;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
import java.util.List;
8+
9+
@Data
10+
@AllArgsConstructor
11+
@NoArgsConstructor
12+
public class ReportGenerateForce {
13+
List<String> reportsId;
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package it.gov.pagopa.idpay.transactions.exception;
2+
3+
public class AzureConnectingErrorException extends RuntimeException{
4+
5+
public AzureConnectingErrorException(String message, Throwable failure) {
6+
super(message, failure);
7+
}
8+
}

src/main/java/it/gov/pagopa/idpay/transactions/service/ReportService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import it.gov.pagopa.idpay.transactions.dto.PatchReportRequest;
55
import it.gov.pagopa.idpay.transactions.dto.ReportDTO;
66
import it.gov.pagopa.idpay.transactions.dto.ReportRequest;
7+
import it.gov.pagopa.idpay.transactions.dto.report.Report2RunDto;
8+
import it.gov.pagopa.idpay.transactions.dto.report.ReportGenerateForce;
79
import it.gov.pagopa.idpay.transactions.model.Report;
810
import org.springframework.data.domain.Page;
911
import org.springframework.data.domain.Pageable;
1012
import reactor.core.publisher.Mono;
1113

14+
import java.util.List;
15+
1216
public interface ReportService {
1317
Mono<Page<Report>> getTransactionsReports(String merchantId, String organizationRole, String initiativeId, Pageable pageable);
1418

@@ -28,4 +32,6 @@ Mono<DownloadReportResponseDTO> downloadTransactionsReport(
2832
String reportId
2933
);
3034

35+
36+
Mono<List<Report2RunDto>> forceGenerateReports(ReportGenerateForce reportGenerateForce);
3137
}

0 commit comments

Comments
 (0)