11package org .mifos .processor .bulk .api .implementation ;
22
3+ import com .fasterxml .jackson .core .type .TypeReference ;
34import com .fasterxml .jackson .databind .ObjectMapper ;
5+ import com .fasterxml .jackson .dataformat .csv .CsvMapper ;
46import lombok .SneakyThrows ;
57import lombok .extern .slf4j .Slf4j ;
68import org .apache .camel .Exchange ;
79import org .apache .camel .ProducerTemplate ;
10+ import org .apache .commons .io .IOUtils ;
811import org .json .JSONObject ;
12+ import org .mifos .connector .common .interceptor .JWSUtil ;
913import org .mifos .processor .bulk .api .definition .BatchTransactions ;
1014import org .mifos .processor .bulk .file .FileStorageService ;
15+ import org .mifos .processor .bulk .format .RestRequestConvertor ;
16+ import org .mifos .processor .bulk .schema .BatchRequestDTO ;
17+ import org .mifos .processor .bulk .schema .CamelApiResponse ;
18+ import org .mifos .processor .bulk .schema .Transaction ;
19+ import org .mifos .processor .bulk .utility .CsvWriter ;
1120import org .mifos .processor .bulk .utility .Headers ;
1221import org .mifos .processor .bulk .utility .SpringWrapperUtil ;
1322import org .springframework .beans .factory .annotation .Autowired ;
23+ import org .springframework .beans .factory .annotation .Value ;
1424import org .springframework .web .bind .annotation .ExceptionHandler ;
1525import org .springframework .web .bind .annotation .RequestHeader ;
1626import org .springframework .web .bind .annotation .RestController ;
1727import org .springframework .web .multipart .MultipartException ;
18- import org . springframework . web . multipart . MultipartFile ;
28+ import javax . servlet . http . HttpServletRequest ;
1929import javax .servlet .http .HttpServletResponse ;
2030import java .io .IOException ;
21-
2231import static org .mifos .processor .bulk .camel .config .CamelProperties .*;
2332import static org .mifos .processor .bulk .zeebe .ZeebeVariables .PURPOSE ;
33+ import java .nio .charset .Charset ;
34+ import java .util .List ;
35+ import java .util .Optional ;
36+ import java .util .UUID ;
37+ import static org .mifos .processor .bulk .camel .config .CamelProperties .HEADER_PROGRAM_ID ;
38+ import static org .mifos .processor .bulk .camel .config .CamelProperties .HEADER_REGISTERING_INSTITUTE_ID ;
2439import static org .mifos .processor .bulk .zeebe .ZeebeVariables .FILE_NAME ;
40+ import static org .mifos .processor .bulk .zeebe .ZeebeVariables .HEADER_CLIENT_CORRELATION_ID ;
41+ import static org .mifos .processor .bulk .zeebe .ZeebeVariables .HEADER_PLATFORM_TENANT_ID ;
42+ import static org .mifos .processor .bulk .zeebe .ZeebeVariables .HEADER_TYPE ;
43+ import static org .mifos .processor .bulk .zeebe .ZeebeVariables .PURPOSE ;
2544
2645@ Slf4j
2746@ RestController
@@ -36,41 +55,118 @@ public class BatchTransactionsController implements BatchTransactions {
3655 @ Autowired
3756 FileStorageService fileStorageService ;
3857
58+ @ Autowired
59+ RestRequestConvertor restRequestConvertor ;
60+
61+ @ Value ("#{'${tenants}'.split(',')}" )
62+ protected List <String > tenants ;
63+ @ Autowired
64+ private CsvMapper csvMapper ;
65+
3966 @ SneakyThrows
4067 @ Override
41- public String batchTransactions (HttpServletResponse httpServletResponse ,
42- String requestId , MultipartFile file , String fileName ,
43- String purpose , String type , String tenant ,
44- String registeringInstitutionId , String programId ) throws IOException {
45- log .debug ("Inside api logic" );
46- String localFileName = fileStorageService .save (file );
47- Headers headers = new Headers .HeaderBuilder ()
68+ public String batchTransactions (
69+ HttpServletRequest httpServletRequest ,
70+ HttpServletResponse httpServletResponse ,
71+ String requestId ,
72+ String fileName ,
73+ String purpose ,
74+ String type ,
75+ String tenant ,
76+ String registeringInstitutionId ,
77+ String programId ) {
78+
79+ log .info ("Inside api logic" );
80+ Headers .HeaderBuilder headerBuilder = new Headers .HeaderBuilder ()
4881 .addHeader (HEADER_CLIENT_CORRELATION_ID , requestId )
49- .addHeader (PURPOSE ,purpose )
50- .addHeader (FILE_NAME ,localFileName )
51- .addHeader ("Type" ,type )
52- .addHeader (HEADER_PLATFORM_TENANT_ID ,tenant )
82+ .addHeader (PURPOSE , purpose )
83+ .addHeader (HEADER_TYPE , type )
84+ .addHeader (HEADER_PLATFORM_TENANT_ID , tenant )
5385 .addHeader (HEADER_REGISTERING_INSTITUTE_ID , registeringInstitutionId )
54- .addHeader (HEADER_PROGRAM_ID , programId )
55- .build ();
56- log .debug ("Headers passed: {}" , headers );
57- Exchange exchange = SpringWrapperUtil .getDefaultWrappedExchange (producerTemplate .getCamelContext (),
58- headers );
59- log .debug ("Header in exchange: {}" , exchange .getIn ().getHeaders ());
86+ .addHeader (HEADER_PROGRAM_ID , programId );
87+
88+ Optional <String > validationResponse = isValidRequest (httpServletRequest , fileName , type );
89+ if (validationResponse .isPresent ()) {
90+ httpServletResponse .setStatus (httpServletResponse .SC_BAD_REQUEST );
91+ return validationResponse .get ();
92+ }
93+
94+ if (JWSUtil .isMultipartRequest (httpServletRequest )) {
95+ log .info ("This is file based request" );
96+ String localFileName = fileStorageService .save (JWSUtil .parseFormData (httpServletRequest ), fileName );
97+ Headers headers = headerBuilder .addHeader (FILE_NAME , localFileName ).build ();
98+ log .info ("Headers passed: {}" , headers .getHeaders ());
99+
100+ CamelApiResponse response = sendRequestToCamel (headers );
101+ httpServletResponse .setStatus (response .getStatus ());
102+ return response .getBody ();
103+ } else {
104+ log .info ("This is json based request" );
105+ String jsonString = IOUtils .toString (httpServletRequest .getInputStream (), Charset .defaultCharset ());
106+ List <BatchRequestDTO > batchRequestDTOList = objectMapper .readValue (jsonString , new TypeReference <>() {});
107+ List <Transaction > transactionList = restRequestConvertor .convertListFrom (batchRequestDTOList );
108+
109+ String localFileName = UUID .randomUUID () + ".csv" ;
110+ CsvWriter .writeToCsv (transactionList , Transaction .class , csvMapper , true , localFileName );
111+ Headers headers = headerBuilder
112+ .addHeader (HEADER_TYPE , "csv" )
113+ .addHeader (FILE_NAME , localFileName ).build ();
114+
115+ CamelApiResponse response = sendRequestToCamel (headers );
116+ httpServletResponse .setStatus (response .getStatus ());
117+ return response .getBody ();
118+ }
119+ }
120+
121+ @ ExceptionHandler ({ MultipartException .class })
122+ public String handleMultipartException (HttpServletResponse httpServletResponse ) {
123+ httpServletResponse .setStatus (httpServletResponse .SC_BAD_REQUEST );
124+ return getErrorResponse ("File not uploaded" , "There was no fie uploaded with the request. " +
125+ "Please upload a file and try again." , 400 );
126+ }
127+
128+ private CamelApiResponse sendRequestToCamel (Headers headers ) {
129+ Exchange exchange = SpringWrapperUtil .getDefaultWrappedExchange (producerTemplate .getCamelContext (), headers );
60130 exchange = producerTemplate .send ("direct:post-batch-transactions" , exchange );
61131 int statusCode = exchange .getIn ().getHeader (Exchange .HTTP_RESPONSE_CODE , Integer .class );
62- httpServletResponse . setStatus ( statusCode );
63- return exchange . getIn (). getBody ( String . class );
132+ String body = exchange . getIn (). getBody ( String . class );
133+ return new CamelApiResponse ( body , statusCode );
64134 }
65135
66- @ ExceptionHandler ({MultipartException .class })
67- public String handleMultipartException (HttpServletResponse httpServletResponse ) {
136+ private String getErrorResponse (String information , String description , int code ) {
68137 JSONObject json = new JSONObject ();
69- json .put ("Error Information: " , "File not uploaded" );
70- json .put ("Error Description : " , "There was no fie uploaded with the request. " +
71- "Please upload a file and try again." );
72- httpServletResponse .setStatus (httpServletResponse .SC_BAD_REQUEST );
138+ json .put ("errorInformation" , "File not uploaded" );
139+ json .put ("errorDescription" , "There was no fie uploaded with the request. " + "Please upload a file and try again." );
140+ json .put ("errorCode" , code );
73141 return json .toString ();
74142 }
75143
144+ // validates the request header, and return errorJson string if the request is invalid else an empty optional
145+ private Optional <String > isValidRequest (HttpServletRequest httpServletRequest ,
146+ String fileName ,
147+ String type ) {
148+
149+ Optional <String > response = Optional .empty ();
150+ if ((JWSUtil .isMultipartRequest (httpServletRequest ) && !type .equalsIgnoreCase ("csv" )) ||
151+ (!JWSUtil .isMultipartRequest (httpServletRequest ) && !type .equalsIgnoreCase ("raw" ))) {
152+ String errorJson = getErrorResponse ("Type mismatch" ,
153+ "The value of the header \" " + HEADER_TYPE +
154+ "\" doesn't match with the request content-type" , 400 );
155+ response = Optional .of (errorJson );
156+
157+ }
158+ if (JWSUtil .isMultipartRequest (httpServletRequest ) && fileName .isEmpty ()) {
159+ String errorJson = getErrorResponse ("Header can't be empty" ,
160+ "If the request is of type csv, the header \" " +
161+ FILE_NAME + "\" can't be empty" , 400 );
162+ response = Optional .of (errorJson );
163+ }
164+ if (!type .equalsIgnoreCase ("raw" ) && !type .equalsIgnoreCase ("csv" )) {
165+ String errorJson = getErrorResponse ("Invalid TYPE header value passed" ,
166+ "The value of the header \" " + HEADER_TYPE +
167+ "\" can be \" [raw,csv]\" but is " + type , 400 );
168+ response = Optional .of (errorJson );
169+ }
170+ return response ;
171+ }
76172}
0 commit comments