Skip to content

Commit be97978

Browse files
committed
Story #15613: Allow validation and sending of transactions with batch errors
1 parent 4ebf9f3 commit be97978

File tree

39 files changed

+390
-66
lines changed

39 files changed

+390
-66
lines changed

api/api-collect/collect/src/main/java/fr/gouv/vitamui/collect/common/dto/CollectTransactionDto.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@
2626
*/
2727
package fr.gouv.vitamui.collect.common.dto;
2828

29+
import fr.gouv.vitam.collect.common.dto.BatchDto;
2930
import fr.gouv.vitamui.commons.api.domain.IdDto;
3031
import lombok.AllArgsConstructor;
3132
import lombok.Builder;
3233
import lombok.Data;
3334
import lombok.EqualsAndHashCode;
3435
import lombok.NoArgsConstructor;
3536

37+
import java.util.List;
38+
3639
@Data
3740
@AllArgsConstructor
3841
@NoArgsConstructor
@@ -58,4 +61,5 @@ public class CollectTransactionDto extends IdDto {
5861
private String lastUpdate;
5962
private String status;
6063
private String projectId;
64+
private List<BatchDto> batches;
6165
}

api/api-collect/collect/src/main/java/fr/gouv/vitamui/collect/server/rest/TransactionController.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727
package fr.gouv.vitamui.collect.server.rest;
2828

29+
import fr.gouv.vitam.collect.common.enums.TransactionValidationMode;
2930
import fr.gouv.vitam.common.error.VitamErrorDetails;
3031
import fr.gouv.vitam.common.exception.VitamClientException;
3132
import fr.gouv.vitamui.archives.search.common.dto.ReclassificationCriteriaDto;
@@ -55,6 +56,7 @@
5556
import org.springframework.web.bind.annotation.RequestBody;
5657
import org.springframework.web.bind.annotation.RequestHeader;
5758
import org.springframework.web.bind.annotation.RequestMapping;
59+
import org.springframework.web.bind.annotation.RequestParam;
5860
import org.springframework.web.bind.annotation.ResponseBody;
5961
import org.springframework.web.bind.annotation.RestController;
6062
import reactor.core.publisher.Mono;
@@ -120,12 +122,18 @@ public void abortTransaction(final @PathVariable("id") String id)
120122

121123
@Secured(ServicesData.ROLE_CLOSE_TRANSACTIONS)
122124
@PutMapping(CommonConstants.PATH_ID + VALIDATE_PATH)
123-
public void validateTransaction(final @PathVariable("id") String id)
124-
throws PreconditionFailedException, VitamClientException {
125+
public void validateTransaction(
126+
final @PathVariable("id") String id,
127+
@RequestParam("validationMode") final TransactionValidationMode validationMode
128+
) throws PreconditionFailedException, VitamClientException {
125129
ParameterChecker.checkParameter(MANDATORY_IDENTIFIER, id);
126130
SanityChecker.checkSecureParameter(id);
127131
LOGGER.debug(TRANSACTION_ID, id);
128-
transactionService.validateTransaction(id, externalParametersService.buildVitamContextFromExternalParam());
132+
transactionService.validateTransaction(
133+
id,
134+
externalParametersService.buildVitamContextFromExternalParam(),
135+
validationMode
136+
);
129137
}
130138

131139
@Operation(summary = "Get transaction by id")

api/api-collect/collect/src/main/java/fr/gouv/vitamui/collect/server/service/TransactionService.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.fasterxml.jackson.databind.node.ArrayNode;
3535
import com.fasterxml.jackson.databind.node.ObjectNode;
3636
import fr.gouv.vitam.collect.common.dto.TransactionDto;
37+
import fr.gouv.vitam.collect.common.enums.TransactionValidationMode;
3738
import fr.gouv.vitam.common.client.VitamContext;
3839
import fr.gouv.vitam.common.error.VitamErrorDetails;
3940
import fr.gouv.vitam.common.exception.InvalidParseOperationException;
@@ -91,9 +92,17 @@ public class TransactionService {
9192

9293
private static final ObjectMapper mapper = new ObjectMapper();
9394

94-
public void validateTransaction(String idTransaction, VitamContext vitamContext) throws VitamClientException {
95+
public void validateTransaction(
96+
String idTransaction,
97+
VitamContext vitamContext,
98+
TransactionValidationMode validationMode
99+
) throws VitamClientException {
95100
try {
96-
RequestResponse requestResponse = collectService.validateTransaction(vitamContext, idTransaction);
101+
RequestResponse requestResponse = collectService.validateTransaction(
102+
vitamContext,
103+
idTransaction,
104+
validationMode
105+
);
97106
if (requestResponse.getStatus() != Response.Status.OK.getStatusCode()) {
98107
throw new VitamClientException("Error occurs when validating transaction!");
99108
}

api/api-collect/collect/src/main/java/fr/gouv/vitamui/collect/server/service/converters/TransactionConverter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public static CollectTransactionDto toVitamUiDto(TransactionDto transactionDto)
6060
collectTransactionDto.setLastUpdate(transactionDto.getLastUpdate());
6161
collectTransactionDto.setProjectId(transactionDto.getProjectId());
6262
collectTransactionDto.setName(transactionDto.getName());
63+
collectTransactionDto.setBatches(transactionDto.getBatches());
6364
return collectTransactionDto;
6465
}
6566

api/api-collect/collect/src/test/java/fr/gouv/vitamui/collect/server/service/TransactionServiceTest.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.fasterxml.jackson.databind.JsonNode;
3434
import com.fasterxml.jackson.databind.ObjectMapper;
3535
import fr.gouv.vitam.collect.common.dto.TransactionDto;
36+
import fr.gouv.vitam.collect.common.enums.TransactionValidationMode;
3637
import fr.gouv.vitam.common.client.VitamContext;
3738
import fr.gouv.vitam.common.error.VitamError;
3839
import fr.gouv.vitam.common.error.VitamErrorDetails;
@@ -84,21 +85,27 @@ class TransactionServiceTest {
8485
@Test
8586
void shouldValidateTransactionWithSuccess() throws VitamClientException {
8687
// GIVEN
87-
when(collectService.validateTransaction(vitamContext, TRANSACTION_ID)).thenReturn(
88-
new RequestResponseOK().setHttpCode(200)
89-
);
88+
when(
89+
collectService.validateTransaction(vitamContext, TRANSACTION_ID, TransactionValidationMode.VALIDATE)
90+
).thenReturn(new RequestResponseOK().setHttpCode(200));
9091
// THEN
91-
assertDoesNotThrow(() -> transactionService.validateTransaction(TRANSACTION_ID, vitamContext));
92+
assertDoesNotThrow(
93+
() ->
94+
transactionService.validateTransaction(TRANSACTION_ID, vitamContext, TransactionValidationMode.VALIDATE)
95+
);
9296
}
9397

9498
@Test
9599
void shouldThrowExceptionWhenValidateTransaction() throws VitamClientException {
96100
// GIVEN
97-
when(collectService.validateTransaction(vitamContext, TRANSACTION_ID)).thenThrow(VitamClientException.class);
101+
when(
102+
collectService.validateTransaction(vitamContext, TRANSACTION_ID, TransactionValidationMode.VALIDATE)
103+
).thenThrow(VitamClientException.class);
98104
// THEN
99105
assertThrows(
100106
VitamClientException.class,
101-
() -> transactionService.validateTransaction(TRANSACTION_ID, vitamContext)
107+
() ->
108+
transactionService.validateTransaction(TRANSACTION_ID, vitamContext, TransactionValidationMode.VALIDATE)
102109
);
103110
}
104111

commons/commons-vitam/src/main/java/fr/gouv/vitamui/commons/vitam/api/collect/CollectService.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import fr.gouv.vitam.collect.common.dto.ProjectDto;
3535
import fr.gouv.vitam.collect.common.dto.TransactionDto;
3636
import fr.gouv.vitam.collect.common.dto.UploadSipResult;
37+
import fr.gouv.vitam.collect.common.enums.TransactionValidationMode;
3738
import fr.gouv.vitam.collect.external.client.CollectExternalClient;
3839
import fr.gouv.vitam.collect.external.external.exception.CollectExternalClientException;
3940
import fr.gouv.vitam.common.CharsetUtils;
@@ -345,10 +346,17 @@ public RequestResponse<JsonNode> deleteProjectById(final VitamContext vitamConte
345346
return result;
346347
}
347348

348-
public RequestResponse validateTransaction(final VitamContext vitamContext, final String idTransaction)
349-
throws VitamClientException {
349+
public RequestResponse validateTransaction(
350+
final VitamContext vitamContext,
351+
final String idTransaction,
352+
final TransactionValidationMode validationMode
353+
) throws VitamClientException {
350354
LOGGER.debug(TRANSACTION_ID, idTransaction);
351-
final RequestResponse response = collectExternalClient.closeTransaction(vitamContext, idTransaction);
355+
final RequestResponse response = collectExternalClient.closeTransaction(
356+
vitamContext,
357+
idTransaction,
358+
validationMode
359+
);
352360
VitamRestUtils.checkResponse(response);
353361
return response;
354362
}

ui/ui-frontend/projects/collect/src/app/collect/archive-search-collect/archive-search-collect.component.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ import { AfterViewInit, Component, OnDestroy, OnInit, TemplateRef, ViewChild } f
3939
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
4040
import { ActivatedRoute } from '@angular/router';
4141
import { TranslateService } from '@ngx-translate/core';
42-
import { BehaviorSubject, finalize, merge, Observable, Subject, Subscription, zip } from 'rxjs';
43-
import { debounceTime, filter, map, mergeMap, share, take, tap } from 'rxjs/operators';
42+
import { BehaviorSubject, finalize, merge, Observable, of, Subject, Subscription, zip } from 'rxjs';
43+
import { debounceTime, filter, map, mergeMap, share, switchMap, take, tap } from 'rxjs/operators';
4444
import { isEmpty } from 'underscore';
4545
import {
4646
AccessContract,
@@ -93,6 +93,7 @@ import {
9393
NODES,
9494
toManagementRuleType,
9595
MANAGEMENT_RULE_SHARED_DATA_SERVICE,
96+
ConfirmDialogComponent,
9697
} from 'vitamui-library';
9798
import { ArchiveCollectService } from './archive-collect.service';
9899
import { SearchCriteriaSaverComponent } from './archive-search-criteria/components/search-criteria-saver/search-criteria-saver.component';
@@ -103,6 +104,7 @@ import { UpdateUnitsMetadataComponent } from './update-units-metadata/update-uni
103104
import { AddUnitsComponent } from './add-units/add-units.component';
104105
import { TransactionsService } from '../transactions/transactions.service';
105106
import { MatCheckboxChange } from '@angular/material/checkbox';
107+
import { TransactionValidationMode } from '../models/transaction-validation-mode.enum';
106108

107109
const PAGE_SIZE = 10;
108110
const ELIMINATION_TECHNICAL_ID = 'ELIMINATION_TECHNICAL_ID';
@@ -1284,14 +1286,34 @@ export class ArchiveSearchCollectComponent extends SidenavPage<any> implements O
12841286
}
12851287

12861288
validateTransaction() {
1287-
this.transactionService
1288-
.validate(this.transaction, { isAutomaticIngest: this.isAutomaticIngest })
1289+
const hasBatchError = this.hasBatchInError(this.transaction);
1290+
const validationMode = hasBatchError ? TransactionValidationMode.VALIDATE_IGNORE : TransactionValidationMode.VALIDATE;
1291+
const confirmation$ = hasBatchError
1292+
? this.dialog
1293+
.open(ConfirmDialogComponent, {
1294+
disableClose: false,
1295+
data: {
1296+
title: 'COLLECT.OTHER_ACTIONS.DIALOG_MESSAGE.CONFIRM_FORCE_TRANSACTION_VALIDATION_MESSAGE',
1297+
subTitle: 'COLLECT.OTHER_ACTIONS.DIALOG_MESSAGE.CONFIRM_TRANSACTION_VALIDATION',
1298+
confirmLabel: 'COLLECT.OTHER_ACTIONS.DIALOG_MESSAGE.CONFIRM_TRANSACTION_VALIDATION',
1299+
cancelLabel: 'COLLECT.OTHER_ACTIONS.DIALOG_MESSAGE.CANCEL',
1300+
},
1301+
})
1302+
.afterClosed()
1303+
.pipe(filter((confirmed) => !!confirmed))
1304+
: of(true);
1305+
1306+
confirmation$
12891307
.pipe(
1290-
finalize(() => {
1291-
this.snackBarService.open({
1292-
message: 'COLLECT.VALIDATE_TRANSACTION_VALIDATED',
1293-
duration: 10_000,
1294-
});
1308+
switchMap(() => {
1309+
return this.transactionService.validate(this.transaction, validationMode, { isAutomaticIngest: this.isAutomaticIngest }).pipe(
1310+
finalize(() => {
1311+
this.snackBarService.open({
1312+
message: 'COLLECT.VALIDATE_TRANSACTION_VALIDATED',
1313+
duration: 10_000,
1314+
});
1315+
}),
1316+
);
12951317
}),
12961318
)
12971319
.subscribe((transaction: Transaction) => {
@@ -1434,5 +1456,9 @@ export class ArchiveSearchCollectComponent extends SidenavPage<any> implements O
14341456
});
14351457
}
14361458

1459+
private hasBatchInError(transaction: Transaction): boolean {
1460+
return transaction.batches?.some((b) => b.BatchStatus === 'KO') ?? false;
1461+
}
1462+
14371463
protected readonly TransactionStatus = TransactionStatus;
14381464
}

ui/ui-frontend/projects/collect/src/app/collect/core/api/transaction-api.service.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* knowledge of the CeCILL-C license and that you accept its terms.
3636
*/
3737

38-
import { HttpClient, HttpHeaders } from '@angular/common/http';
38+
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
3939
import { Inject, Injectable } from '@angular/core';
4040
import { Observable } from 'rxjs';
4141
import {
@@ -49,6 +49,7 @@ import {
4949
Unit,
5050
VitamErrorDetails,
5151
} from 'vitamui-library';
52+
import { TransactionValidationMode } from '../../models/transaction-validation-mode.enum';
5253

5354
@Injectable({
5455
providedIn: 'root',
@@ -71,8 +72,9 @@ export class TransactionApiService extends PaginatedHttpClient<Transaction> {
7172
return this.http.get<Transaction>(this.apiUrl + '/' + transactionId);
7273
}
7374

74-
validateTransaction(id: string) {
75-
return this.http.put<Transaction>(this.apiUrl + '/' + id + '/validate', {});
75+
validateTransaction(id: string, validationMode: TransactionValidationMode) {
76+
const params = new HttpParams().set('validationMode', validationMode);
77+
return this.http.put<Transaction>(this.apiUrl + '/' + id + '/validate', {}, { params });
7678
}
7779

7880
sendTransaction(id: string) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022)
3+
* and the signatories of the "VITAM - Accord du Contributeur" agreement.
4+
*
5+
* contact@programmevitam.fr
6+
*
7+
* This software is a computer program whose purpose is to implement
8+
* implement a digital archiving front-office system for the secure and
9+
* efficient high volumetry VITAM solution.
10+
*
11+
* This software is governed by the CeCILL-C license under French law and
12+
* abiding by the rules of distribution of free software. You can use,
13+
* modify and/ or redistribute the software under the terms of the CeCILL-C
14+
* license as circulated by CEA, CNRS and INRIA at the following URL
15+
* "http://www.cecill.info".
16+
*
17+
* As a counterpart to the access to the source code and rights to copy,
18+
* modify and redistribute granted by the license, users are provided only
19+
* with a limited warranty and the software's author, the holder of the
20+
* economic rights, and the successive licensors have only limited
21+
* liability.
22+
*
23+
* In this respect, the user's attention is drawn to the risks associated
24+
* with loading, using, modifying and/or developing or reproducing the
25+
* software by the user in light of its specific status of free software,
26+
* that may mean that it is complicated to manipulate, and that also
27+
* therefore means that it is reserved for developers and experienced
28+
* professionals having in-depth computer knowledge. Users are therefore
29+
* encouraged to load and test the software's suitability as regards their
30+
* requirements in conditions enabling the security of their systems and/or
31+
* data to be ensured and, more generally, to use and operate it in the
32+
* same conditions as regards security.
33+
*
34+
* The fact that you are presently reading this means that you have had
35+
* knowledge of the CeCILL-C license and that you accept its terms.
36+
*/
37+
export enum TransactionValidationMode {
38+
VALIDATE = 'VALIDATE',
39+
VALIDATE_IGNORE = 'VALIDATE_IGNORE',
40+
VALIDATE_FORCE = 'VALIDATE_FORCE',
41+
}

ui/ui-frontend/projects/collect/src/app/collect/transactions/transaction-list/transaction-list.component.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44
justify-content: flex-end; /* ✅ pousse les boutons à droite */
55
}
66

7+
.batch-ko-error {
8+
color: var(--vitamui-red);
9+
}
10+
711

0 commit comments

Comments
 (0)