You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by GitBox <gi...@apache.org> on 2020/08/04 12:48:27 UTC

[GitHub] [fineract] rrpawar96 opened a new pull request #1235: Creditbureau phase 3 Integration

rrpawar96 opened a new pull request #1235:
URL: https://github.com/apache/fineract/pull/1235


   ## Description
   Describe the changes made and why they were made. Ignore if these details are present on the associated Jira ticket
   
   ## Checklist
   Please make sure these boxes are checked before submitting your pull request - thanks!
   
   - [ ] Commit message starts with the issue number from https://issues.apache.org/jira/projects/FINERACT/. Ex: FINERACT-646 Pockets API.
   
   - [ ] Coding conventions at https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions have been followed.
   
   - [ ] API documentation at fineract-provider/src/main/resources/static/api-docs/apiLive.htm has been updated with details of any API changes.
   
   - [ ] Integration tests have been created/updated for verifying the changes made.
   
   - [ ] All Integrations tests are passing with the new commits.
   
   - [ ] Submission is not a "code dump".  (Large changes can be made "in repository" via a branch.  Ask on the list.)
   
   Our guidelines for code reviews is at https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r522466052



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,

Review comment:
       It would be even better not to code at this low level, but use a higher level ready made HTTP Client library. Do you know if https://square.github.io/okhttp/ and https://square.github.io/retrofit/? Both are already used in Fineract, search the existing code for examples how to use it...




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r519473947



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+                CreditReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                LOG.info("Credit Bureau Id {} not found", creditBureauID);
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    @Override
+    public String addCreditReport(File report, Long bureauId) {
+
+        Optional<String> creditBureauName = getCreditBureau(bureauId);
+
+        if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+
+            Integer creditBureauId = bureauId.intValue();
+
+            // make lower case
+            CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionId");
+            CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionKey");
+            CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+            CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+            String subscriptionId = "";
+            String subscriptionKey = "";
+            String userName = "";
+            String password = "";
+
+            try {
+                subscriptionId = subscriptionIdData.getValue();
+                subscriptionKey = subscriptionKeyData.getValue();
+                userName = userNameData.getValue();
+                password = passwordData.getValue();
+            } catch (NullPointerException ex) {

Review comment:
       Instead of catching NPE here, Can we check if CreditBureauConfiguration itself is Null, if yes, not move ahead

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        HttpURLConnection httpConnection = null;
+
+        try {
+            if (process.equals("token")) {
+
+                URL tokenurl = new URL(url);
+                httpConnection = (HttpURLConnection) tokenurl.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+
+                URL NrcURL = new URL(url + nrcID);
+                httpConnection = (HttpURLConnection) NrcURL.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("CreditReport")) {
+
+                URL CreditReportURL = new URL(url + uniqueID);
+                httpConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                httpConnection.setRequestMethod("GET");
+
+            } else if (process.equals("UploadCreditReport")) {
+
+                URL addCreditReporturl = new URL(url);
+                httpConnection = (HttpURLConnection) addCreditReporturl.openConnection();
+                httpConnection.setRequestMethod("POST");
+            }
+
+            // common set of headers
+            httpConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            httpConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return httpConnection;
+    }
+
+    public String httpResponse(HttpURLConnection httpConnection) {
+
+        String result = null; // return type of this method
+        try {
+            int responseCode = httpConnection.getResponseCode();
+
+            StringBuilder response = new StringBuilder();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), StandardCharsets.UTF_8));
+
+                String readLine = null;
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+                LOG.info("----- result-----{}", result);
+
+            } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_UNAUTHORIZED";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_FORBIDDEN";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    @SuppressWarnings("StringSplitter")
+    public CreditReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
+
+        this.context.authenticatedUser();
+        String nrcId = command.stringValueOfParameterNamed("NRC");
+        String bureauID = command.stringValueOfParameterNamed("creditBureauID");
+        Integer creditBureauId = Integer.parseInt(bureauID);
+
+        CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionId");
+        CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionKey");
+        CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+        CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+        String subscriptionId = "";
+        String subscriptionKey = "";
+        String userName = "";
+        String password = "";
+
+        try {
+            subscriptionId = subscriptionIdData.getValue();
+            subscriptionKey = subscriptionKeyData.getValue();
+            userName = userNameData.getValue();
+            password = passwordData.getValue();
+        } catch (NullPointerException ex) {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available" + ex);
+        }
+
+        String token = null;
+        if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {
+            token = createToken(userName, password, subscriptionId, subscriptionKey, creditBureauId);
+        } else {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available");
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        String process = "NRC";
+        CreditBureauConfiguration SearchURL = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "searchurl");
+        String url = SearchURL.getValue();
+        String result = this.httpConnectionMethod(process, nrcId, userName, password, subscriptionKey, subscriptionId, url, token, 0L,
+                null);
+
+        // after fetching the data from httpconnection it will be come back here for fetching UniqueID from data
+        if (process.equals("NRC")) {
+
+            JsonObject reportObject = JsonParser.parseString(result).getAsJsonObject();
+
+            JsonElement element = reportObject.get("Data");
+
+            if (element.isJsonNull()) {
+                String ResponseMessage = reportObject.get("ResponseMessage").getAsString();
+                handleAPIIntegrityIssues(ResponseMessage);
+            }
+
+            // to fetch the Unique ID from Result
+            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
+            Long uniqueID = 0L;
+            try {
+                JsonArray jArray = jsonObject.getAsJsonArray("Data");
+                JsonObject jobject = jArray.get(0).getAsJsonObject();
+                String uniqueIdString = jobject.get("UniqueID").toString();
+
+                String TrimUniqueId = uniqueIdString.substring(1, uniqueIdString.length() - 1);
+                uniqueID = Long.parseLong(TrimUniqueId);
+            } catch (IndexOutOfBoundsException e) {
+                String ResponseMessage = reportObject.get("ResponseMessage").getAsString();
+                handleAPIIntegrityIssues(ResponseMessage);
+            }
+
+            process = "CreditReport";
+            CreditBureauConfiguration creditReportURL = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "creditReporturl");
+            url = creditReportURL.getValue();
+            result = this.httpConnectionMethod(process, nrcId, userName, password, subscriptionKey, subscriptionId, url, token, uniqueID,
+                    null);
+
+        }
+
+        // after getting the result(creditreport) from httpconnection-response it will assign creditreport to generic
+        // creditreportdata object
+
+        JsonObject reportObject = JsonParser.parseString(result).getAsJsonObject();
+
+        JsonObject borrowerInfos = null;
+        String borrowerInfo = null;
+        String CreditScore = null;
+        String ActiveLoans = null;
+        String PaidLoans = null;
+
+        // Credit Reports Stored into Generic CreditReportData
+        JsonObject data = null;
+        JsonElement element = reportObject.get("Data");
+
+        if (!(element instanceof JsonNull)) { // NOTE : "element instanceof JsonNull" is for handling empty values (and
+                                              // assigning null) while fetching data from results
+            data = (JsonObject) element;
+        }
+
+        borrowerInfo = null;
+        element = data.get("BorrowerInfo");
+        if (!(element instanceof JsonNull)) {
+            borrowerInfos = (JsonObject) element;

Review comment:
       extract this repeating logic in method

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,

Review comment:
       I think we can break this method down to two methods, getHTTPPostConnection() and getHTTPGetConnection(). Let me know if you agree.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+                CreditReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                LOG.info("Credit Bureau Id {} not found", creditBureauID);
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    @Override
+    public String addCreditReport(File report, Long bureauId) {
+
+        Optional<String> creditBureauName = getCreditBureau(bureauId);
+
+        if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+
+            Integer creditBureauId = bureauId.intValue();
+
+            // make lower case
+            CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionId");
+            CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionKey");
+            CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+            CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+            String subscriptionId = "";
+            String subscriptionKey = "";
+            String userName = "";
+            String password = "";
+
+            try {
+                subscriptionId = subscriptionIdData.getValue();
+                subscriptionKey = subscriptionKeyData.getValue();
+                userName = userNameData.getValue();
+                password = passwordData.getValue();
+            } catch (NullPointerException ex) {
+                throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                        "Credit Bureau Configuration is not available" + ex);
+            }
+
+            LOG.info("subscriptionIdData {}", subscriptionIdData + "subscriptionId {}", subscriptionId);
+
+            if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {

Review comment:
       you can check if there is common string class method which would check if string is null or empty, instead of repeating logic everywhere. If there isn't try to create one mehtod. ex boolisStringNullOrEmpty(String str) {
   if (str != null && !str.isEmpty()) {
   return true;} return false;}    or may be come up with more better checks

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+                CreditReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                LOG.info("Credit Bureau Id {} not found", creditBureauID);
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    @Override
+    public String addCreditReport(File report, Long bureauId) {
+
+        Optional<String> creditBureauName = getCreditBureau(bureauId);
+
+        if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+
+            Integer creditBureauId = bureauId.intValue();
+
+            // make lower case
+            CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionId");

Review comment:
       Can we have subscriptionId and other config params as enums?

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        HttpURLConnection httpConnection = null;
+
+        try {
+            if (process.equals("token")) {
+
+                URL tokenurl = new URL(url);
+                httpConnection = (HttpURLConnection) tokenurl.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+
+                URL NrcURL = new URL(url + nrcID);
+                httpConnection = (HttpURLConnection) NrcURL.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("CreditReport")) {
+
+                URL CreditReportURL = new URL(url + uniqueID);
+                httpConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                httpConnection.setRequestMethod("GET");
+
+            } else if (process.equals("UploadCreditReport")) {
+
+                URL addCreditReporturl = new URL(url);
+                httpConnection = (HttpURLConnection) addCreditReporturl.openConnection();
+                httpConnection.setRequestMethod("POST");
+            }
+
+            // common set of headers
+            httpConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            httpConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return httpConnection;
+    }
+
+    public String httpResponse(HttpURLConnection httpConnection) {
+
+        String result = null; // return type of this method
+        try {
+            int responseCode = httpConnection.getResponseCode();
+
+            StringBuilder response = new StringBuilder();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), StandardCharsets.UTF_8));
+
+                String readLine = null;
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+                LOG.info("----- result-----{}", result);
+
+            } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_UNAUTHORIZED";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_FORBIDDEN";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    @SuppressWarnings("StringSplitter")
+    public CreditReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
+
+        this.context.authenticatedUser();
+        String nrcId = command.stringValueOfParameterNamed("NRC");
+        String bureauID = command.stringValueOfParameterNamed("creditBureauID");
+        Integer creditBureauId = Integer.parseInt(bureauID);
+
+        CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionId");
+        CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionKey");
+        CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+        CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+        String subscriptionId = "";
+        String subscriptionKey = "";
+        String userName = "";
+        String password = "";
+
+        try {
+            subscriptionId = subscriptionIdData.getValue();
+            subscriptionKey = subscriptionKeyData.getValue();
+            userName = userNameData.getValue();
+            password = passwordData.getValue();
+        } catch (NullPointerException ex) {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available" + ex);
+        }
+
+        String token = null;
+        if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {
+            token = createToken(userName, password, subscriptionId, subscriptionKey, creditBureauId);
+        } else {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available");
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        String process = "NRC";
+        CreditBureauConfiguration SearchURL = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "searchurl");
+        String url = SearchURL.getValue();
+        String result = this.httpConnectionMethod(process, nrcId, userName, password, subscriptionKey, subscriptionId, url, token, 0L,
+                null);
+
+        // after fetching the data from httpconnection it will be come back here for fetching UniqueID from data
+        if (process.equals("NRC")) {
+
+            JsonObject reportObject = JsonParser.parseString(result).getAsJsonObject();
+
+            JsonElement element = reportObject.get("Data");
+
+            if (element.isJsonNull()) {
+                String ResponseMessage = reportObject.get("ResponseMessage").getAsString();
+                handleAPIIntegrityIssues(ResponseMessage);
+            }
+
+            // to fetch the Unique ID from Result
+            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
+            Long uniqueID = 0L;
+            try {
+                JsonArray jArray = jsonObject.getAsJsonArray("Data");
+                JsonObject jobject = jArray.get(0).getAsJsonObject();
+                String uniqueIdString = jobject.get("UniqueID").toString();

Review comment:
       extract this logic in method. Can we validate uniqueId, instead of depending on IndexOutOfBoundsExcp

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        HttpURLConnection httpConnection = null;
+
+        try {
+            if (process.equals("token")) {
+
+                URL tokenurl = new URL(url);
+                httpConnection = (HttpURLConnection) tokenurl.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+
+                URL NrcURL = new URL(url + nrcID);
+                httpConnection = (HttpURLConnection) NrcURL.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("CreditReport")) {
+
+                URL CreditReportURL = new URL(url + uniqueID);
+                httpConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                httpConnection.setRequestMethod("GET");
+
+            } else if (process.equals("UploadCreditReport")) {
+
+                URL addCreditReporturl = new URL(url);
+                httpConnection = (HttpURLConnection) addCreditReporturl.openConnection();
+                httpConnection.setRequestMethod("POST");
+            }
+
+            // common set of headers
+            httpConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            httpConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return httpConnection;
+    }
+
+    public String httpResponse(HttpURLConnection httpConnection) {
+
+        String result = null; // return type of this method
+        try {
+            int responseCode = httpConnection.getResponseCode();
+
+            StringBuilder response = new StringBuilder();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), StandardCharsets.UTF_8));
+
+                String readLine = null;
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+                LOG.info("----- result-----{}", result);
+
+            } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_UNAUTHORIZED";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_FORBIDDEN";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    @SuppressWarnings("StringSplitter")
+    public CreditReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
+
+        this.context.authenticatedUser();
+        String nrcId = command.stringValueOfParameterNamed("NRC");
+        String bureauID = command.stringValueOfParameterNamed("creditBureauID");
+        Integer creditBureauId = Integer.parseInt(bureauID);
+
+        CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionId");
+        CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionKey");
+        CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+        CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+        String subscriptionId = "";
+        String subscriptionKey = "";
+        String userName = "";
+        String password = "";
+
+        try {
+            subscriptionId = subscriptionIdData.getValue();

Review comment:
       i gave feedback regarding this approach above.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        HttpURLConnection httpConnection = null;
+
+        try {
+            if (process.equals("token")) {
+
+                URL tokenurl = new URL(url);
+                httpConnection = (HttpURLConnection) tokenurl.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+
+                URL NrcURL = new URL(url + nrcID);
+                httpConnection = (HttpURLConnection) NrcURL.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("CreditReport")) {
+
+                URL CreditReportURL = new URL(url + uniqueID);
+                httpConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                httpConnection.setRequestMethod("GET");
+
+            } else if (process.equals("UploadCreditReport")) {
+
+                URL addCreditReporturl = new URL(url);
+                httpConnection = (HttpURLConnection) addCreditReporturl.openConnection();
+                httpConnection.setRequestMethod("POST");
+            }
+
+            // common set of headers
+            httpConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            httpConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return httpConnection;
+    }
+
+    public String httpResponse(HttpURLConnection httpConnection) {
+
+        String result = null; // return type of this method
+        try {
+            int responseCode = httpConnection.getResponseCode();
+
+            StringBuilder response = new StringBuilder();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), StandardCharsets.UTF_8));
+
+                String readLine = null;
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+                LOG.info("----- result-----{}", result);
+
+            } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_UNAUTHORIZED";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_FORBIDDEN";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    @SuppressWarnings("StringSplitter")
+    public CreditReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
+
+        this.context.authenticatedUser();
+        String nrcId = command.stringValueOfParameterNamed("NRC");
+        String bureauID = command.stringValueOfParameterNamed("creditBureauID");
+        Integer creditBureauId = Integer.parseInt(bureauID);
+
+        CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionId");
+        CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionKey");
+        CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+        CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+        String subscriptionId = "";
+        String subscriptionKey = "";
+        String userName = "";
+        String password = "";
+
+        try {
+            subscriptionId = subscriptionIdData.getValue();
+            subscriptionKey = subscriptionKeyData.getValue();
+            userName = userNameData.getValue();
+            password = passwordData.getValue();
+        } catch (NullPointerException ex) {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available" + ex);
+        }
+
+        String token = null;
+        if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {
+            token = createToken(userName, password, subscriptionId, subscriptionKey, creditBureauId);
+        } else {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available");
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        String process = "NRC";
+        CreditBureauConfiguration SearchURL = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "searchurl");
+        String url = SearchURL.getValue();
+        String result = this.httpConnectionMethod(process, nrcId, userName, password, subscriptionKey, subscriptionId, url, token, 0L,
+                null);
+
+        // after fetching the data from httpconnection it will be come back here for fetching UniqueID from data
+        if (process.equals("NRC")) {

Review comment:
       extract a method of NRC process

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        HttpURLConnection httpConnection = null;
+
+        try {
+            if (process.equals("token")) {
+
+                URL tokenurl = new URL(url);
+                httpConnection = (HttpURLConnection) tokenurl.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+
+                URL NrcURL = new URL(url + nrcID);
+                httpConnection = (HttpURLConnection) NrcURL.openConnection();
+                httpConnection.setRequestMethod("POST");
+
+            } else if (process.equals("CreditReport")) {
+
+                URL CreditReportURL = new URL(url + uniqueID);
+                httpConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                httpConnection.setRequestMethod("GET");
+
+            } else if (process.equals("UploadCreditReport")) {
+
+                URL addCreditReporturl = new URL(url);
+                httpConnection = (HttpURLConnection) addCreditReporturl.openConnection();
+                httpConnection.setRequestMethod("POST");
+            }
+
+            // common set of headers
+            httpConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            httpConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return httpConnection;
+    }
+
+    public String httpResponse(HttpURLConnection httpConnection) {
+
+        String result = null; // return type of this method
+        try {
+            int responseCode = httpConnection.getResponseCode();
+
+            StringBuilder response = new StringBuilder();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+
+                BufferedReader in = new BufferedReader(new InputStreamReader(httpConnection.getInputStream(), StandardCharsets.UTF_8));
+
+                String readLine = null;
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+                LOG.info("----- result-----{}", result);
+
+            } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_UNAUTHORIZED";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
+                LOG.info("-----IP FORBIDDEN-----");
+                String httpResponse = "HTTP_FORBIDDEN";
+                this.handleAPIIntegrityIssues(httpResponse);
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+    }
+
+    @Transactional
+    @Override
+    @SuppressWarnings("StringSplitter")
+    public CreditReportData getCreditReportFromThitsaWorks(final JsonCommand command) {
+
+        this.context.authenticatedUser();
+        String nrcId = command.stringValueOfParameterNamed("NRC");
+        String bureauID = command.stringValueOfParameterNamed("creditBureauID");
+        Integer creditBureauId = Integer.parseInt(bureauID);
+
+        CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionId");
+        CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                "SubscriptionKey");
+        CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+        CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+        String subscriptionId = "";
+        String subscriptionKey = "";
+        String userName = "";
+        String password = "";
+
+        try {
+            subscriptionId = subscriptionIdData.getValue();
+            subscriptionKey = subscriptionKeyData.getValue();
+            userName = userNameData.getValue();
+            password = passwordData.getValue();
+        } catch (NullPointerException ex) {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available" + ex);
+        }
+
+        String token = null;
+        if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {
+            token = createToken(userName, password, subscriptionId, subscriptionKey, creditBureauId);
+        } else {
+            throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                    "Credit Bureau Configuration is not available");
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        String process = "NRC";
+        CreditBureauConfiguration SearchURL = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "searchurl");

Review comment:
       don't start with caps for url names, applies throughout the PR.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r532088067



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,

Review comment:
       @rrpawar96 I see that you've switched to using OkHTTP now, looks great, thank you; I'm therefore resolving this comment. FYI @nikpawar89.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r522466052



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.java
##########
@@ -0,0 +1,420 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Service
+public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
+
+    @Transactional
+    @Override
+    public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
+            String subscriptionId, String url, String token, Long uniqueID, File report) {
+
+        String result = null;
+
+        try {
+            String post_params = null;
+            HttpURLConnection httpConnection = this.process(process, nrcID, userName, password, subscriptionKey, subscriptionId, url, token,
+                    uniqueID, report);
+
+            if (process.equals("token")) {
+                post_params = "" + "BODY=x-www-form-urlencoded&\r" + "grant_type=password&\r" + "userName=" + userName + "&\r" + "password="
+                        + password + "&\r";
+            } else if (process.equals("NRC")) {
+
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcID + "&";
+            } else if (process.equals("UploadCreditReport")) {
+
+                post_params = "BODY=formdata&" + report + "&" + "userName=" + userName + "&";
+            }
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                httpConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set is required only for (POST METHOD)- fetching uniqueID from NRC/Creating Token/Add Credit report
+            if (process.equals("NRC") || process.equals("token") || process.equals("UploadCreditReport")) {
+                httpConnection.setDoOutput(true);
+                OutputStream os = httpConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+            }
+
+            result = this.httpResponse(httpConnection);
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+        return result;
+
+    }
+
+    private HttpURLConnection process(String process, String nrcID, String userName, String password, String subscriptionKey,

Review comment:
       It would be even better not to code at this low level, but use a higher level ready made HTTP Client library. Do you know of https://square.github.io/okhttp/ and https://square.github.io/retrofit/? Both are already used in Fineract, search the existing code for examples how to use it...




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r499332023



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -95,7 +95,7 @@ public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext contex
     private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
 
     public String httpConnectionMethod(String process, String nrcID, String userName, String password, String subscriptionKey,
-            String subscriptionId, String url, String token, Long uniqueID) {
+            String subscriptionId, String url, String token, Long uniqueID, File report) {

Review comment:
       why are we using File in http request




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882805



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java
##########
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Entity
+@Table(name = "m_creditreport")
+public final class CreditReport extends AbstractPersistableCustom {
+
+    @Column(name = "creditBureauId")
+    private Long creditBureauId;
+
+    @Column(name = "nrc")
+    private String nrc;

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882442



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauReportData.java
##########
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditBureauReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final String name;
+
+    private final String gender;
+
+    private final String address;
+
+    private final String creditScore;
+
+    private final String borrowerInfo;
+
+    private final String activeLoans;

Review comment:
       Comment Addressed. Implemented String[] instead of Plain String




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492518373



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {

Review comment:
       Kept it public to make it accessible for test case




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: Creditbureau phase 3 Integration

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-669755663


   Could you please a open a JIRA issue for this, so that it appears on the
   Release Notes?
   
   >
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492522178



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,121 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauToken.class);
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String accessToken;
+
+    @Column(name = "token_type")
+    private String tokenType;
+
+    @Column(name = "expires_in")
+    private String expiresIn;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")
+    private Date expires;
+
+    public CreditBureauToken(String userName, String accessToken, String tokenType, String expiresIn, String issued, Date expires) {
+        this.userName = userName;
+        this.accessToken = accessToken;
+        this.tokenType = tokenType;
+        this.expiresIn = expiresIn;
+        this.issued = issued;
+        this.expires = expires;
+    }
+
+    public CreditBureauToken() {
+        this.userName = null;
+        this.accessToken = null;
+        this.tokenType = null;
+        this.expiresIn = null;
+        this.issued = null;
+        this.expires = null;
+    }
+
+    public static CreditBureauToken fromJson(final JsonCommand command) {
+        final String userName = command.stringValueOfParameterNamed("userName");
+        final String accessToken = command.stringValueOfParameterNamed("access_token");
+        final String tokenType = command.stringValueOfParameterNamed("token_type");
+        final String expiresIn = command.stringValueOfParameterNamed("expires_in");
+        final String issued = command.stringValueOfParameterNamed(".issued");
+        final String expiry = command.stringValueOfParameterNamed(".expires");
+
+        LOG.info("Expiry {}", expiry);
+
+        DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882937



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+    private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
+            .resource("creditBureauIntegration");
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl) {
+        this.context = context;
+        this.configDataRepository = configDataRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    }
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+                throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                        dataValidationErrors);
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                // CreditBureauToken creditBureauToken = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                // .createToken(creditBureauID);
+
+                CreditBureauReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+
+                // return new
+                // CommandProcessingResultBuilder().withCreditReport(reportobj).withCreditBureauToken(creditBureauToken).build();
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+            throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                    dataValidationErrors);
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    // saving the fetched creditreport in database
+    @Override
+    @Transactional
+    public CommandProcessingResult saveCreditReport(Long creditBureauId, String creditReportNumber, JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauId);
+            CreditReport creditReport = null;
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, creditReportNumber);
+
+                // checks whether the creditReport for same NRC was saved before. if yes, then deletes it and replaces
+                // it with new one.
+                if (creditReport != null) {
+                    this.creditReportRepository.delete(creditReport);
+                    creditReport = null;

Review comment:
       comment addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882911



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+    private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
+            .resource("creditBureauIntegration");
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl) {
+        this.context = context;
+        this.configDataRepository = configDataRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    }
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+                throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                        dataValidationErrors);
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                // CreditBureauToken creditBureauToken = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                // .createToken(creditBureauID);
+
+                CreditBureauReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+
+                // return new
+                // CommandProcessingResultBuilder().withCreditReport(reportobj).withCreditBureauToken(creditBureauToken).build();
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+            throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                    dataValidationErrors);
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    // saving the fetched creditreport in database
+    @Override
+    @Transactional
+    public CommandProcessingResult saveCreditReport(Long creditBureauId, String creditReportNumber, JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauId);
+            CreditReport creditReport = null;
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, creditReportNumber);
+
+                // checks whether the creditReport for same NRC was saved before. if yes, then deletes it and replaces
+                // it with new one.
+                if (creditReport != null) {
+                    this.creditReportRepository.delete(creditReport);
+                    creditReport = null;
+                }
+
+                if (creditReport == null) {

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492522601



##########
File path: fineract-provider/config/swagger/fineract-input.yaml
##########
@@ -0,0 +1,37 @@
+openapi: 3.0.3

Review comment:
       No, So it has been removed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548881191



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauConfigurations.java
##########
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+public enum CreditBureauConfigurations {
+
+    THITSAWORKS, subscriptionId, subscriptionKey, userName, password;

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-752376531


   Documentation: https://cwiki.apache.org/confluence/display/FINERACT/Documentation+to+use+Integrated+Credit+Bureau
   It's ready to get merge @vorburger @nikpawar89 @awasum 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-754115125


   Merged based on @nikpawar89 LGTM above 7 days ago. @rrpawar96 Thank You for contributing! More to come?  😸 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r522461934



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+                CreditReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                LOG.info("Credit Bureau Id {} not found", creditBureauID);
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    @Override
+    public String addCreditReport(File report, Long bureauId) {
+
+        Optional<String> creditBureauName = getCreditBureau(bureauId);
+
+        if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+
+            Integer creditBureauId = bureauId.intValue();
+
+            // make lower case
+            CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionId");
+            CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionKey");
+            CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+            CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+            String subscriptionId = "";
+            String subscriptionKey = "";
+            String userName = "";
+            String password = "";
+
+            try {
+                subscriptionId = subscriptionIdData.getValue();
+                subscriptionKey = subscriptionKeyData.getValue();
+                userName = userNameData.getValue();
+                password = passwordData.getValue();
+            } catch (NullPointerException ex) {
+                throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                        "Credit Bureau Configuration is not available" + ex);
+            }
+
+            LOG.info("subscriptionIdData {}", subscriptionIdData + "subscriptionId {}", subscriptionId);
+
+            if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {

Review comment:
       There is one in Commons Lang and in Guava.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r468293737



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportData.java
##########
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final Object creditScore;

Review comment:
       change the datatypes to actual datatypes

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,101 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String access_token;
+
+    @Column(name = "token_type")
+    private String token_type;
+
+    @Column(name = "expires_in")
+    private String expires_in;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")

Review comment:
       why String is used instead of date.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");

Review comment:
       don't hard code time zones

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();

Review comment:
       change data type to Date and come up with better way to compare dates

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauTokenCredential.java
##########
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+
+@Entity

Review comment:
       Come up with more generic design to store configurations of credit bureau, we can't have one table per credit bureau for storing configurations. You may have to refactor this token module.

##########
File path: fineract-provider/src/main/resources/sql/migrations/core_db/V273__oauth_changes.sql
##########
@@ -59,3 +59,42 @@ CREATE TABLE `oauth_refresh_token` (
 )
 COLLATE='utf8mb4_general_ci'
 ENGINE=InnoDB;
+
+CREATE TABLE `m_creditbureau_tokendata` (
+  `id` INT(128) NOT NULL AUTO_INCREMENT,
+  `userNames` varchar(128) DEFAULT NULL,
+  `password` varchar(128) DEFAULT NULL,
+  `subscription_id` varchar(128) DEFAULT NULL,
+  `subscription_key` varchar(128) DEFAULT NULL,
+
+  PRIMARY KEY (`id`)
+)
+COLLATE='utf8mb4_general_ci'
+ENGINE=InnoDB;
+
+INSERT INTO `m_creditbureau_tokendata` (`id`, `userNames`, `password`, `subscription_id`, `subscription_key`) VALUES
+('1', 'demomfi1@gmail.com','Sampleuser123*' ,'317A1FF8-625D-41BA-BE0F-F8ED8A644A7C', 'cb225c15ff1742feab2f1fb444393ace'),
+('2', 'demomfi2@gmail.com','Sampleuser123*' ,'B76FEFF5-5B42-4A36-AFDA-AB5C7398220C', '91ce69a972b14c7fab057788fe61ce8a'),
+('3', 'demomfi3@gmail.com','Sampleuser123*' ,'31333A80-BDE7-43EE-B1FD-6699C518AF85', '86f4f58542554e0ba9a309003eadd1fc'),
+('4', 'demomfi4@gmail.com','Sampleuser123*' ,'C929C107-E779-4233-8493-176CF6DEA251', '302ed3b928df43ccb0de97f008b07320');
+
+-- permissions added
+
+
+INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'CREATE_CREDITBUREAUTOKEN', 'CREDITBUREAUTOKEN', 'CREATE', 0);
+INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('configuration', 'CREATE_CREDITBUREAUTOKENDATA', 'CREDITBUREAUTOKENDATA', 'CREATE', 0);
+
+CREATE TABLE `m_creditbureau_token` (

Review comment:
       come up with more generic design to store configs.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauTokenWritePlatformServiceImpl.java
##########
@@ -0,0 +1,178 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonElement;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauTokenWritePlatformServiceImpl implements CreditBureauTokenWritePlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauTokenWritePlatformServiceImpl.class);
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final CreditBureauTokenRepository creditBureauTokenRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final CreditBureauToken creditBureauToken;
+    private final TokenDataRepository tokendatRepository;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private static String tokenstr;
+    private final JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    public CreditBureauTokenWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final CreditBureauTokenRepository creditBureauTokenRepository, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository, final TokenDataRepository tokendatRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer, final FromJsonHelper fromApiJsonHelper,
+            final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final CreditBureauToken creditBureauToken,
+            final RoutingDataSource dataSource) {
+        this.context = context;
+        this.creditBureauTokenRepository = creditBureauTokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.tokenRepository = tokenRepository;
+        this.tokendatRepository = tokendatRepository;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.readPlatformServiceCreditBureauToken = readPlatformServiceCreditBureauToken;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.creditBureauToken = creditBureauToken;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "credittoken", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CommandProcessingResult createCreditBureauToken(JsonCommand command) {
+        try {
+            this.context.authenticatedUser();
+
+            // fetch the token credentials for using it in header
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+
+            final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                    + "&\r\n" + "password=" + password + "&\r\n";
+
+            URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+            String readLine = null;
+
+            HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
+            postConnection.setRequestMethod("POST");

Review comment:
       extract http connection code into method

##########
File path: fineract-provider/src/main/resources/sql/migrations/core_db/V273__oauth_changes.sql
##########
@@ -59,3 +59,42 @@ CREATE TABLE `oauth_refresh_token` (
 )
 COLLATE='utf8mb4_general_ci'
 ENGINE=InnoDB;
+
+CREATE TABLE `m_creditbureau_tokendata` (
+  `id` INT(128) NOT NULL AUTO_INCREMENT,
+  `userNames` varchar(128) DEFAULT NULL,
+  `password` varchar(128) DEFAULT NULL,
+  `subscription_id` varchar(128) DEFAULT NULL,
+  `subscription_key` varchar(128) DEFAULT NULL,
+
+  PRIMARY KEY (`id`)
+)
+COLLATE='utf8mb4_general_ci'
+ENGINE=InnoDB;
+
+INSERT INTO `m_creditbureau_tokendata` (`id`, `userNames`, `password`, `subscription_id`, `subscription_key`) VALUES

Review comment:
       this data should not be given. Take this out

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);

Review comment:
       Please be consistent with date data types, use either of date, LocalDate or LocalDateTime.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);
+                    LOG.info("local date : {} ", date);
+
+                    if (getExpiryDate.before(current)) {
+                        LOG.info("The token is expired");
+                        final CreditBureauToken credittoken = this.tokenRepository.getToken();
+                        if (credittoken != null) {
+
+                            this.tokenRepository.delete(credittoken);
+                            creditbureautoken = null;
+                        }
+
+                    }
+
+                } catch (ParseException Ex) {
+                    LOG.error("Error occured.", Ex);
+                }
+            }
+
+            // if token is not available or previous token is expired then create a new token
+            if (creditbureautoken == null) {
+
+                LOG.info("-----creating new token-----");
+                final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                        + "&\r\n" + "password=" + password + "&\r\n";
+
+                URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                String readLine = null;
+
+                HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();

Review comment:
       encapsulate http connection into method, so that it can be resued.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);
+                    LOG.info("local date : {} ", date);
+
+                    if (getExpiryDate.before(current)) {
+                        LOG.info("The token is expired");
+                        final CreditBureauToken credittoken = this.tokenRepository.getToken();
+                        if (credittoken != null) {
+
+                            this.tokenRepository.delete(credittoken);
+                            creditbureautoken = null;
+                        }
+
+                    }
+
+                } catch (ParseException Ex) {
+                    LOG.error("Error occured.", Ex);
+                }
+            }
+
+            // if token is not available or previous token is expired then create a new token
+            if (creditbureautoken == null) {
+
+                LOG.info("-----creating new token-----");
+                final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                        + "&\r\n" + "password=" + password + "&\r\n";
+
+                URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                String readLine = null;
+
+                HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
+                postConnection.setRequestMethod("POST");
+                postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+                postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+                postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+                postConnection.setDoOutput(true);
+
+                OutputStream os = postConnection.getOutputStream();
+                os.write(POST_PARAMS.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+                int responseCode = postConnection.getResponseCode();
+
+                String ResponseMessage = postConnection.getResponseMessage();
+
+                if (responseCode == HttpURLConnection.HTTP_OK) {
+                    BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                    StringBuilder response = new StringBuilder();
+                    while ((readLine = in.readLine()) != null) {
+                        response.append(readLine);
+                    }
+                    in.close();
+
+                    result = response.toString();
+
+                    final CommandWrapper wrapper = new CommandWrapperBuilder().withJson(result).build();
+                    final String json = wrapper.getJson();
+                    result = null;
+                    JsonCommand apicommand = null;
+                    boolean isApprovedByChecker = false;
+                    final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
+
+                    apicommand = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
+                            wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(),
+                            wrapper.getLoanId(), wrapper.getSavingsId(), wrapper.getTransactionId(), wrapper.getHref(),
+                            wrapper.getProductId(), wrapper.getCreditBureauId(), wrapper.getOrganisationCreditBureauId());
+
+                    this.fromApiJsonDeserializer.validateForCreate(apicommand.json());
+
+                    final CreditBureauToken generatedtoken = CreditBureauToken.fromJson(apicommand);
+
+                    this.tokenRepository.save(generatedtoken);
+
+                } else {
+                    LOG.info("Request is Invalid");
+
+                }
+            }
+
+            // Search Methods
+            LOG.info("-----Search by NRC-----");
+            StringBuilder response = new StringBuilder();
+            creditbureautoken = this.tokenRepository.getToken();
+            String token = creditbureautoken.getCurrentToken();
+
+            final String POST_PARAMS = "BODY=x-www-form-urlencoded&nrc=" + searchId + "&";
+
+            URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + searchId);
+            String readLine = null;
+            LOG.info("POST_PARAMS : {} ", POST_PARAMS);
+            LOG.info("obj : {} ", obj);
+            LOG.info("subscriptionId : {} ", subscriptionId);
+            LOG.info("subscriptionKey : {} ", subscriptionKey);
+            LOG.info("token : {} ", token);
+
+            HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();

Review comment:
       refactor http connection into method.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-696892087


    @rrpawar96 is this still a work in progress, or something that you would like to be reviewed and merged when OK? If so, then click the Ready for Review button above, to remove the Draft status. (If not, just keep working on it like this, as you are.)


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r474867130



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);
+                    LOG.info("local date : {} ", date);
+
+                    if (getExpiryDate.before(current)) {
+                        LOG.info("The token is expired");
+                        final CreditBureauToken credittoken = this.tokenRepository.getToken();
+                        if (credittoken != null) {
+
+                            this.tokenRepository.delete(credittoken);
+                            creditbureautoken = null;
+                        }
+
+                    }
+
+                } catch (ParseException Ex) {
+                    LOG.error("Error occured.", Ex);
+                }
+            }
+
+            // if token is not available or previous token is expired then create a new token
+            if (creditbureautoken == null) {
+
+                LOG.info("-----creating new token-----");
+                final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                        + "&\r\n" + "password=" + password + "&\r\n";
+
+                URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                String readLine = null;
+
+                HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String result = null;
+        Long uniqueID = 0L;
+        try {
+            this.context.authenticatedUser();
+
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+            String tokenDate;
+
+            CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+            LOG.info("credit bureau token : {} ", creditbureautoken);
+
+            // check the expiry date of the previous token.
+            if (creditbureautoken != null) {
+                try {
+                    Date current = new Date();
+
+                    String getDate = creditbureautoken.getTokenExpiryDate();
+                    DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+                    Date getExpiryDate = dateformat.parse(getDate);
+                    LOG.info("current date : {} ", current);
+                    LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+                    ZoneId zid = ZoneId.of("Asia/Rangoon");
+                    final LocalDate date = LocalDate.now(zid);
+                    LOG.info("local date : {} ", date);
+
+                    if (getExpiryDate.before(current)) {
+                        LOG.info("The token is expired");
+                        final CreditBureauToken credittoken = this.tokenRepository.getToken();
+                        if (credittoken != null) {
+
+                            this.tokenRepository.delete(credittoken);
+                            creditbureautoken = null;
+                        }
+
+                    }
+
+                } catch (ParseException Ex) {
+                    LOG.error("Error occured.", Ex);
+                }
+            }
+
+            // if token is not available or previous token is expired then create a new token
+            if (creditbureautoken == null) {
+
+                LOG.info("-----creating new token-----");
+                final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                        + "&\r\n" + "password=" + password + "&\r\n";
+
+                URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                String readLine = null;
+
+                HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
+                postConnection.setRequestMethod("POST");
+                postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+                postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+                postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+                postConnection.setDoOutput(true);
+
+                OutputStream os = postConnection.getOutputStream();
+                os.write(POST_PARAMS.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+                int responseCode = postConnection.getResponseCode();
+
+                String ResponseMessage = postConnection.getResponseMessage();
+
+                if (responseCode == HttpURLConnection.HTTP_OK) {
+                    BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                    StringBuilder response = new StringBuilder();
+                    while ((readLine = in.readLine()) != null) {
+                        response.append(readLine);
+                    }
+                    in.close();
+
+                    result = response.toString();
+
+                    final CommandWrapper wrapper = new CommandWrapperBuilder().withJson(result).build();
+                    final String json = wrapper.getJson();
+                    result = null;
+                    JsonCommand apicommand = null;
+                    boolean isApprovedByChecker = false;
+                    final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
+
+                    apicommand = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(),
+                            wrapper.getEntityId(), wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(),
+                            wrapper.getLoanId(), wrapper.getSavingsId(), wrapper.getTransactionId(), wrapper.getHref(),
+                            wrapper.getProductId(), wrapper.getCreditBureauId(), wrapper.getOrganisationCreditBureauId());
+
+                    this.fromApiJsonDeserializer.validateForCreate(apicommand.json());
+
+                    final CreditBureauToken generatedtoken = CreditBureauToken.fromJson(apicommand);
+
+                    this.tokenRepository.save(generatedtoken);
+
+                } else {
+                    LOG.info("Request is Invalid");
+
+                }
+            }
+
+            // Search Methods
+            LOG.info("-----Search by NRC-----");
+            StringBuilder response = new StringBuilder();
+            creditbureautoken = this.tokenRepository.getToken();
+            String token = creditbureautoken.getCurrentToken();
+
+            final String POST_PARAMS = "BODY=x-www-form-urlencoded&nrc=" + searchId + "&";
+
+            URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + searchId);
+            String readLine = null;
+            LOG.info("POST_PARAMS : {} ", POST_PARAMS);
+            LOG.info("obj : {} ", obj);
+            LOG.info("subscriptionId : {} ", subscriptionId);
+            LOG.info("subscriptionKey : {} ", subscriptionKey);
+            LOG.info("token : {} ", token);
+
+            HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauTokenWritePlatformServiceImpl.java
##########
@@ -0,0 +1,178 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonElement;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauTokenWritePlatformServiceImpl implements CreditBureauTokenWritePlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauTokenWritePlatformServiceImpl.class);
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final CreditBureauTokenRepository creditBureauTokenRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final CreditBureauToken creditBureauToken;
+    private final TokenDataRepository tokendatRepository;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private static String tokenstr;
+    private final JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    public CreditBureauTokenWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final CreditBureauTokenRepository creditBureauTokenRepository, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository, final TokenDataRepository tokendatRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer, final FromJsonHelper fromApiJsonHelper,
+            final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final CreditBureauToken creditBureauToken,
+            final RoutingDataSource dataSource) {
+        this.context = context;
+        this.creditBureauTokenRepository = creditBureauTokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.tokenRepository = tokenRepository;
+        this.tokendatRepository = tokendatRepository;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.readPlatformServiceCreditBureauToken = readPlatformServiceCreditBureauToken;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.creditBureauToken = creditBureauToken;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "credittoken", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CommandProcessingResult createCreditBureauToken(JsonCommand command) {
+        try {
+            this.context.authenticatedUser();
+
+            // fetch the token credentials for using it in header
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+
+            final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                    + "&\r\n" + "password=" + password + "&\r\n";
+
+            URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+            String readLine = null;
+
+            HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
+            postConnection.setRequestMethod("POST");

Review comment:
       comment has been addressed

##########
File path: fineract-provider/src/main/resources/sql/migrations/core_db/V273__oauth_changes.sql
##########
@@ -59,3 +59,42 @@ CREATE TABLE `oauth_refresh_token` (
 )
 COLLATE='utf8mb4_general_ci'
 ENGINE=InnoDB;
+
+CREATE TABLE `m_creditbureau_tokendata` (
+  `id` INT(128) NOT NULL AUTO_INCREMENT,
+  `userNames` varchar(128) DEFAULT NULL,
+  `password` varchar(128) DEFAULT NULL,
+  `subscription_id` varchar(128) DEFAULT NULL,
+  `subscription_key` varchar(128) DEFAULT NULL,
+
+  PRIMARY KEY (`id`)
+)
+COLLATE='utf8mb4_general_ci'
+ENGINE=InnoDB;
+
+INSERT INTO `m_creditbureau_tokendata` (`id`, `userNames`, `password`, `subscription_id`, `subscription_key`) VALUES

Review comment:
       comment has been addressed




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882775



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java
##########
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CreditReportReadPlatformServiceImpl implements CreditReportReadPlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+
+    @Autowired
+    public CreditReportReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    private static final class CreditReportDataMapper implements RowMapper<CreditReportData> {
+
+        public String schema() {
+            return " c.id as id, c.creditBureauId as creditBureauId , c.nrc as nrc from m_creditreport c ";
+        }
+
+        @Override
+        public CreditReportData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
+
+            final Long id = rs.getLong("id");
+            final Long creditBureauId = rs.getLong("creditBureauId");
+            final String nrc = rs.getString("nrc");
+            // final byte[] creditReports = rs.getBytes("creditReports");
+
+            return CreditReportData.instance(id, creditBureauId, nrc);// , creditReports);
+        }
+    }
+
+    @Override
+    public Collection<CreditReportData> retrieveCreditReport(Long creditBureauId) {

Review comment:
       we are retreiving creditReportDetails, so to avoid confusion, renamed it from retrieveCreditReport to retrieveCreditReportDetails, will use this to download/delete creditReports in further enhancement.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-735316716


   > > Travis CI - Pull Request Failing after 3m — Build Failed
   > 
   > ```
   > CommandProcessingResult.java:50: error: no suitable constructor found for CommandProcessingResult(Long,Long,Long,Long,Long,Long,String,Long,String,Map<String,Object>,Long,Long,Long,Boolean,Long)
   > ```
   > 
   > @rrpawar96 did you notice this ^^^ build failure? Perhaps if you fix it @nikpawar89 will re-review this, so that we can merge it soon?
   
   @rrpawar96 per our last conversation, you were testing this code. Is this PR stale, could you please check. @vorburger  I will have a final look, once @rrpawar96 completes testing, if you have any additional feedback, please feel free to mention here.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-737022994


   > After creating this pr, there are a lot of changes that happened, so will do the functional testing of this PR with the UI and when it will be ready to fully re-review, will let you know.
   
   @rrpawar96 if you do not want this PR to be reviewed and merged yet, could you _Mark it as Draft_ (click button on the right?).


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882837



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReportRepository.java
##########
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+public interface CreditReportRepository extends JpaRepository<CreditReport, Long>, JpaSpecificationExecutor<CreditReport> {
+
+    @Query("SELECT creditBureauReport from CreditReport creditBureauReport where creditBureauReport.nrc = :nrc and creditBureauReport.creditBureauId = :creditBureauId ")
+    CreditReport getThitsaWorksCreditReport(@Param("creditBureauId") Long creditBureauId, @Param("nrc") String nrc);

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r546415588



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauConfigurations.java
##########
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+public enum CreditBureauConfigurations {
+
+    THITSAWORKS, subscriptionId, subscriptionKey, userName, password;

Review comment:
       enum values should be all caps

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java
##########
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Entity
+@Table(name = "m_creditreport")
+public final class CreditReport extends AbstractPersistableCustom {
+
+    @Column(name = "creditBureauId")
+    private Long creditBureauId;
+
+    @Column(name = "nrc")
+    private String nrc;

Review comment:
       you can rename nrc to nationalID to make it sound as generic

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {

Review comment:
       this should be fetch credit report not post

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
+
+        Gson gson = new Gson();
+        final String json = gson.toJson(params);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // saves fetched-creditreport into database
+    @POST
+    @Path("saveCreditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
+            @QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @QueryParam("creditReportNumber") @Parameter(description = "creditReportNumber") final String creditReportNumber) {
+
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .saveCreditReport(creditBureauId, creditReportNumber) // creditReportNumber is a NRC number for
+                                                                      // Thitsawork
+                .withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is a creditReport
+                .build(); //
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
+    @GET
+    @Path("creditReport/{creditBureauId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String getSavedCreditReport(@PathParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @Context final UriInfo uriInfo) {
+
+        this.context.authenticatedUser();
+
+        final Collection<CreditReportData> creditReport = this.creditReportReadPlatformService.retrieveCreditReport(creditBureauId);
+
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, creditReport, RESPONSE_DATA_PARAMETERS);
+
+    }
+
+    // deletes saved creditReports from database
+    @DELETE
+    @Path("deleteCreditReport/{creditBureauId}")

Review comment:
       rename creditBureauID to creditReportID

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
+
+        Gson gson = new Gson();
+        final String json = gson.toJson(params);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // saves fetched-creditreport into database
+    @POST
+    @Path("saveCreditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
+            @QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @QueryParam("creditReportNumber") @Parameter(description = "creditReportNumber") final String creditReportNumber) {
+
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .saveCreditReport(creditBureauId, creditReportNumber) // creditReportNumber is a NRC number for
+                                                                      // Thitsawork
+                .withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is a creditReport
+                .build(); //
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
+    @GET
+    @Path("creditReport/{creditBureauId}")

Review comment:
       rename creditBureauID to creditReportID

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauReportData.java
##########
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditBureauReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final String name;
+
+    private final String gender;
+
+    private final String address;
+
+    private final String creditScore;
+
+    private final String borrowerInfo;
+
+    private final String activeLoans;

Review comment:
       is this plain string or do you want to put this in array or some collection?

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauReportData.java
##########
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditBureauReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final String name;
+
+    private final String gender;
+
+    private final String address;
+
+    private final String creditScore;
+
+    private final String borrowerInfo;
+
+    private final String activeLoans;
+
+    private final String paidLoans;

Review comment:
       same here, this could be multiple accounts, so you may want to put it in array/collections. You may also rename this to closedAccounts and rename activeLoans to openAccounts. I am fine if you don't rename it.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReportRepository.java
##########
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+public interface CreditReportRepository extends JpaRepository<CreditReport, Long>, JpaSpecificationExecutor<CreditReport> {
+
+    @Query("SELECT creditBureauReport from CreditReport creditBureauReport where creditBureauReport.nrc = :nrc and creditBureauReport.creditBureauId = :creditBureauId ")
+    CreditReport getThitsaWorksCreditReport(@Param("creditBureauId") Long creditBureauId, @Param("nrc") String nrc);

Review comment:
        I think If you rename nrc to nationalID, I would say other credit bureaus would also have such a ID. So this can be generic as well. We may revisit this later, if we think this is not the case.
   
   

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java
##########
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CreditReportReadPlatformServiceImpl implements CreditReportReadPlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+
+    @Autowired
+    public CreditReportReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    private static final class CreditReportDataMapper implements RowMapper<CreditReportData> {
+
+        public String schema() {
+            return " c.id as id, c.creditBureauId as creditBureauId , c.nrc as nrc from m_creditreport c ";
+        }
+
+        @Override
+        public CreditReportData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
+
+            final Long id = rs.getLong("id");
+            final Long creditBureauId = rs.getLong("creditBureauId");
+            final String nrc = rs.getString("nrc");
+            // final byte[] creditReports = rs.getBytes("creditReports");
+
+            return CreditReportData.instance(id, creditBureauId, nrc);// , creditReports);
+        }
+    }
+
+    @Override
+    public Collection<CreditReportData> retrieveCreditReport(Long creditBureauId) {

Review comment:
       I don't see we are retrieving credit report.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauReportData.java
##########
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditBureauReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final String name;
+
+    private final String gender;
+
+    private final String address;
+
+    private final String creditScore;
+
+    private final String borrowerInfo;
+
+    private final String activeLoans;
+
+    private final String paidLoans;
+
+    /*
+     * private final Object borrowerInformation; private final Object creditScore; private final Object activeLoans;

Review comment:
       remove commented code.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+    private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
+            .resource("creditBureauIntegration");
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl) {
+        this.context = context;
+        this.configDataRepository = configDataRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    }
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+                throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                        dataValidationErrors);
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                // CreditBureauToken creditBureauToken = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                // .createToken(creditBureauID);
+
+                CreditBureauReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+
+                // return new
+                // CommandProcessingResultBuilder().withCreditReport(reportobj).withCreditBureauToken(creditBureauToken).build();
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+            throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                    dataValidationErrors);
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    // saving the fetched creditreport in database
+    @Override
+    @Transactional
+    public CommandProcessingResult saveCreditReport(Long creditBureauId, String creditReportNumber, JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauId);
+            CreditReport creditReport = null;
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, creditReportNumber);
+
+                // checks whether the creditReport for same NRC was saved before. if yes, then deletes it and replaces
+                // it with new one.
+                if (creditReport != null) {
+                    this.creditReportRepository.delete(creditReport);
+                    creditReport = null;
+                }
+
+                if (creditReport == null) {

Review comment:
       I don't think you need to check if null here, it would always be null.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauConfigurations;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureauReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final PlatformSecurityContext context;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    private final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
+    private final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
+            .resource("creditBureauIntegration");
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl) {
+        this.context = context;
+        this.configDataRepository = configDataRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl = thitsaWorksCreditBureauIntegrationWritePlatformServiceImpl;
+    }
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+                throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                        dataValidationErrors);
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                // CreditBureauToken creditBureauToken = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                // .createToken(creditBureauID);
+
+                CreditBureauReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+
+                // return new
+                // CommandProcessingResultBuilder().withCreditReport(reportobj).withCreditBureauToken(creditBureauToken).build();
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            baseDataValidator.reset().failWithCode("creditBureau.has.not.been.Integrated");
+            throw new PlatformApiDataValidationException("creditBureau.has.not.been.Integrated", "creditBureau.has.not.been.Integrated",
+                    dataValidationErrors);
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    // saving the fetched creditreport in database
+    @Override
+    @Transactional
+    public CommandProcessingResult saveCreditReport(Long creditBureauId, String creditReportNumber, JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauId);
+            CreditReport creditReport = null;
+
+            if (Objects.equals(creditBureauName.get(), CreditBureauConfigurations.THITSAWORKS.toString())) {
+
+                creditReport = creditReportRepository.getThitsaWorksCreditReport(creditBureauId, creditReportNumber);
+
+                // checks whether the creditReport for same NRC was saved before. if yes, then deletes it and replaces
+                // it with new one.
+                if (creditReport != null) {
+                    this.creditReportRepository.delete(creditReport);
+                    creditReport = null;

Review comment:
       don't set it as null and remove the null check below




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492518552



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] github-actions[bot] commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
github-actions[bot] commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-696453111


   This pull request seems to be stale.  Are you still planning to work on it?  We will automatically close it in 30 days.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882520



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditBureauReportData.java
##########
@@ -0,0 +1,62 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditBureauReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final String name;
+
+    private final String gender;
+
+    private final String address;
+
+    private final String creditScore;
+
+    private final String borrowerInfo;
+
+    private final String activeLoans;
+
+    private final String paidLoans;

Review comment:
       Comment Addressed. Implemented String[] instead of Plain String and renamed the parameters to openAccounts and closedAccounts




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r532088457



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.Optional;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReport;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditReportRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final CreditReportRepository creditReportRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository, final CreditReportRepository creditReportRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.creditReportRepository = creditReportRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            Long creditBureauID = command.longValueOfParameterNamed("creditBureauID");
+
+            Optional<String> creditBureauName = getCreditBureau(creditBureauID);
+
+            if (creditBureauName.isEmpty()) {
+                throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+            }
+
+            if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+                CreditReportData reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService
+                        .getCreditReportFromThitsaWorks(command);
+                return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+            }
+
+            throw new PlatformDataIntegrityException("Credit Bureau has not been Integrated", "Credit Bureau has not been Integrated");
+
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private Optional<String> getCreditBureau(Long creditBureauID) {
+
+        if (creditBureauID != null) {
+            Optional<CreditBureau> creditBureau = this.creditBureauRepository.findById(creditBureauID);
+
+            if (creditBureau.isEmpty()) {
+                LOG.info("Credit Bureau Id {} not found", creditBureauID);
+                return Optional.empty();
+            }
+
+            return Optional.of(creditBureau.get().getName());
+
+        }
+
+        return Optional.empty();
+    }
+
+    @Override
+    public String addCreditReport(File report, Long bureauId) {
+
+        Optional<String> creditBureauName = getCreditBureau(bureauId);
+
+        if (Objects.equals(creditBureauName.get(), CreditBureaNames.THITSAWORKS.toString())) {
+
+            Integer creditBureauId = bureauId.intValue();
+
+            // make lower case
+            CreditBureauConfiguration subscriptionIdData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionId");
+            CreditBureauConfiguration subscriptionKeyData = this.configDataRepository.getCreditBureauConfigData(creditBureauId,
+                    "SubscriptionKey");
+            CreditBureauConfiguration userNameData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Username");
+            CreditBureauConfiguration passwordData = this.configDataRepository.getCreditBureauConfigData(creditBureauId, "Password");
+
+            String subscriptionId = "";
+            String subscriptionKey = "";
+            String userName = "";
+            String password = "";
+
+            try {
+                subscriptionId = subscriptionIdData.getValue();
+                subscriptionKey = subscriptionKeyData.getValue();
+                userName = userNameData.getValue();
+                password = passwordData.getValue();
+            } catch (NullPointerException ex) {
+                throw new PlatformDataIntegrityException("Credit Bureau Configuration is not available",
+                        "Credit Bureau Configuration is not available" + ex);
+            }
+
+            LOG.info("subscriptionIdData {}", subscriptionIdData + "subscriptionId {}", subscriptionId);
+
+            if (!"".equals(subscriptionId) && !"".equals(subscriptionKey) && !"".equals(userName) && !"".equals(password)) {

Review comment:
       @rrpawar96 this code is no longer there and seems to have moved now? Anyway, I see that you are now using `StringUtils.defaultIfEmpty(newValue, null)` in `CreditBureauConfiguration` so shall we resolve this comment now @nikpawar89?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r512404839



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,234 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.util.NoSuchElementException;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            String creditBureauID = command.stringValueOfParameterNamed("creditBureauID");
+
+            String creditBureauName = getCreditBureau(creditBureauID);
+
+            CreditReportData reportobj = null;
+
+            if (creditBureauName.equals(CreditBureaNames.THITSAWORKS.toString())) {
+                reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService.getCreditReportFromThitsaWorks(command);
+            }
+
+            return new CommandProcessingResultBuilder().withCreditReport(reportobj).build();
+        } catch (final DataIntegrityViolationException dve) {
+            handleTokenDataIntegrityIssues(command, dve.getMostSpecificCause(), dve);
+            return CommandProcessingResult.empty();
+        } catch (final PersistenceException ee) {
+            Throwable throwable = ExceptionUtils.getRootCause(ee.getCause());
+            handleTokenDataIntegrityIssues(command, throwable, ee);
+            return CommandProcessingResult.empty();
+        }
+
+    }
+
+    private String getCreditBureau(final String creditBureauID) {
+
+        String creditBureauName = null;
+        CreditBureau creditBureau = null;
+        if (creditBureauID != null) {
+
+            Long bureauID = Long.parseLong(creditBureauID);
+
+            try {
+                creditBureau = this.creditBureauRepository.findById(bureauID).get();

Review comment:
       potential null pointer excption




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r474867077



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,101 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String access_token;
+
+    @Column(name = "token_type")
+    private String token_type;
+
+    @Column(name = "expires_in")
+    private String expires_in;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")

Review comment:
       comment has been addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger merged pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger merged pull request #1235:
URL: https://github.com/apache/fineract/pull/1235


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-723540175


   @rrpawar96 apparently this has conflicts that need to be resolved? @nikpawar89 once conflicts are resolved, is this good for you as is?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r549417967



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
+
+        Gson gson = new Gson();
+        final String json = gson.toJson(params);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // saves fetched-creditreport into database
+    @POST
+    @Path("saveCreditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
+            @QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @QueryParam("creditReportNumber") @Parameter(description = "creditReportNumber") final String creditReportNumber) {
+
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .saveCreditReport(creditBureauId, creditReportNumber) // creditReportNumber is a NRC number for
+                                                                      // Thitsawork
+                .withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is a creditReport
+                .build(); //
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
+    @GET
+    @Path("creditReport/{creditBureauId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String getSavedCreditReport(@PathParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @Context final UriInfo uriInfo) {
+
+        this.context.authenticatedUser();
+
+        final Collection<CreditReportData> creditReport = this.creditReportReadPlatformService.retrieveCreditReport(creditBureauId);
+
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, creditReport, RESPONSE_DATA_PARAMETERS);
+
+    }
+
+    // deletes saved creditReports from database
+    @DELETE
+    @Path("deleteCreditReport/{creditBureauId}")

Review comment:
       alright




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] github-actions[bot] commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
github-actions[bot] commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-696453111


   This pull request seems to be stale.  Are you still planning to work on it?  We will automatically close it in 30 days.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492522694



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-696892087


    @rrpawar96 is this still a work in progress, or something that you would like to be reviewed and merged when OK? If so, then click the Ready for Review button above, to remove the Draft status. (If not, just keep working on it like this, as you are.)


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-723640366


   > @rrpawar96 apparently this has conflicts that need to be resolved? @nikpawar89 once conflicts are resolved, is this good for you as is?
   
   I am going to take a look again, @rrpawar96 @vorburger 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r474866976



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportData.java
##########
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.data;
+
+import java.io.Serializable;
+
+public final class CreditReportData implements Serializable {
+
+    @SuppressWarnings("unused")
+    private final Object creditScore;

Review comment:
       comment has been addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-751789995


   Looks good to me, please attach test evidence and create wiki for community use.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492519683



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")

Review comment:
       Removed CacheEvict

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String Name = null;
+        String Gender = null;
+        nrcId = searchId;
+        String Address = null;
+
+        this.context.authenticatedUser();
+
+        final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+        if (credittokendata != null) {
+            userName = credittokendata.getUserName();
+            password = credittokendata.getPassword();
+            subscriptionId = credittokendata.getSubscriptionId();
+            subscriptionKey = credittokendata.getSubscriptionKey();
+
+            // validation required, incase when configuration is not stored in database while fetching data.
+        } else {
+
+            String configJson = "{ 'userName':'" + userName + "','password':'" + password + "','subscriptionId':'" + subscriptionId
+                    + "','subscriptionKey':'" + subscriptionKey + "'}";
+
+            this.fromApiJsonDeserializer.validateForUsingTokenConfig(configJson);
+        }
+
+        CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+        LOG.info("creditbureautoken : {} ", creditbureautoken);
+
+        // check the expiry date of the previous token.
+        if (creditbureautoken != null) {
+            Date current = new Date();
+            Date getExpiryDate = creditbureautoken.getTokenExpiryDate();
+
+            LOG.info("current date : {} ", current);
+            LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+            if (getExpiryDate.before(current)) {
+                LOG.info("The token is expired");
+                this.tokenRepository.delete(creditbureautoken);
+                creditbureautoken = null;
+            }
+        }
+        // storing token if it is valid token(not expired)
+        if (creditbureautoken != null) {
+            token = creditbureautoken.getCurrentToken();
+        }
+
+        // if token is not available or previous token is expired then create a new token
+        if (creditbureautoken == null) {
+
+            // using common http connection method for creating token
+            process = "token";
+            this.httpConnectionMethod();
+
+            JsonObject tokenObject = JsonParser.parseString(result).getAsJsonObject();
+            String expiresextra = tokenObject.get(".expires").toString();
+            String expires = expiresextra.substring(1, expiresextra.length() - 1);
+            DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-746818548


   The PR is ready for re-review. @vorburger  @nikpawar89 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r512404952



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditReportWritePlatformServiceImpl.java
##########
@@ -0,0 +1,234 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.util.NoSuchElementException;
+import javax.persistence.PersistenceException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditBureaNames;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureau;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfiguration;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauConfigurationRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauLoanProductMappingRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditReportWritePlatformServiceImpl implements CreditReportWritePlatformService {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauLoanProductMappingRepository loanProductMappingRepository;
+    private final CreditBureauRepository creditBureauRepository;
+    private final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService;
+
+    @Autowired
+    public CreditReportWritePlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final CreditBureauConfigurationRepositoryWrapper configDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer,
+            final CreditBureauLoanProductMappingRepository loanProductMappingRepository,
+            final CreditBureauRepository creditBureauRepository,
+            final ThitsaWorksCreditBureauIntegrationWritePlatformService thitsaWorksCreditBureauIntegrationWritePlatformService) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.configDataRepository = configDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.loanProductMappingRepository = loanProductMappingRepository;
+        this.creditBureauRepository = creditBureauRepository;
+        this.thitsaWorksCreditBureauIntegrationWritePlatformService = thitsaWorksCreditBureauIntegrationWritePlatformService;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditReportWritePlatformServiceImpl.class);
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    public CommandProcessingResult getCreditReport(JsonCommand command) {
+
+        try {
+            this.context.authenticatedUser();
+
+            String creditBureauID = command.stringValueOfParameterNamed("creditBureauID");
+
+            String creditBureauName = getCreditBureau(creditBureauID);
+
+            CreditReportData reportobj = null;
+
+            if (creditBureauName.equals(CreditBureaNames.THITSAWORKS.toString())) {
+                reportobj = this.thitsaWorksCreditBureauIntegrationWritePlatformService.getCreditReportFromThitsaWorks(command);

Review comment:
       I think, if string does not match you should let client know,




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] awasum commented on pull request #1235: Creditbureau phase 3 Integration

Posted by GitBox <gi...@apache.org>.
awasum commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-668579254


   What are the specs or JIRA for this PR? 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: Creditbureau phase 3 Integration

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-668679749


   Specs of this PR: https://cwiki.apache.org/confluence/display/FINERACT/Credit+Bureau+Integration+Phase+3


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] vorburger commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
vorburger commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-735269797


   >  Travis CI - Pull Request Failing after 3m — Build Failed 
   
       CommandProcessingResult.java:50: error: no suitable constructor found for CommandProcessingResult(Long,Long,Long,Long,Long,Long,String,Long,String,Map<String,Object>,Long,Long,Long,Boolean,Long)
   
   @rrpawar96 did you notice this ^^^ build failure? Perhaps if you fix it @nikpawar89 will re-review this, so that we can merge it soon?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548881154



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548883182



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
+
+        Gson gson = new Gson();
+        final String json = gson.toJson(params);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // saves fetched-creditreport into database
+    @POST
+    @Path("saveCreditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
+            @QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @QueryParam("creditReportNumber") @Parameter(description = "creditReportNumber") final String creditReportNumber) {
+
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .saveCreditReport(creditBureauId, creditReportNumber) // creditReportNumber is a NRC number for
+                                                                      // Thitsawork
+                .withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is a creditReport
+                .build(); //
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
+    @GET
+    @Path("creditReport/{creditBureauId}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String getSavedCreditReport(@PathParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @Context final UriInfo uriInfo) {
+
+        this.context.authenticatedUser();
+
+        final Collection<CreditReportData> creditReport = this.creditReportReadPlatformService.retrieveCreditReport(creditBureauId);
+
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.toApiJsonSerializer.serialize(settings, creditReport, RESPONSE_DATA_PARAMETERS);
+
+    }
+
+    // deletes saved creditReports from database
+    @DELETE
+    @Path("deleteCreditReport/{creditBureauId}")

Review comment:
       we will need two parameters(creditBureauId/nationalId) to delete the saved CreditReports in database. So creditBureauId is passing from pathparam and nationalId is passing from body




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492518909



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r499327647



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,118 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauToken.class);
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String accessToken;
+
+    @Column(name = "token_type")
+    private String tokenType;
+
+    @Column(name = "expires_in")
+    private String expiresIn;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")
+    private Date expires;
+
+    public CreditBureauToken(String userName, String accessToken, String tokenType, String expiresIn, String issued, Date expires) {
+        this.userName = userName;
+        this.accessToken = accessToken;
+        this.tokenType = tokenType;
+        this.expiresIn = expiresIn;
+        this.issued = issued;
+        this.expires = expires;
+    }
+
+    public CreditBureauToken() {
+        this.userName = null;
+        this.accessToken = null;
+        this.tokenType = null;
+        this.expiresIn = null;
+        this.issued = null;
+        this.expires = null;
+    }
+
+    public static CreditBureauToken fromJson(final JsonCommand command) {
+        final String userName = command.stringValueOfParameterNamed("userName");
+        final String accessToken = command.stringValueOfParameterNamed("access_token");
+        final String tokenType = command.stringValueOfParameterNamed("token_type");
+        final String expiresIn = command.stringValueOfParameterNamed("expires_in");
+        final String issued = command.stringValueOfParameterNamed(".issued");
+        final String expiry = command.stringValueOfParameterNamed(".expires");
+
+        SimpleDateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       is this the format of date we get from creditbureau?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-735424106


   After creating this pr, there are a lot of changes that happened, so will do the functional testing of this PR with the UI and when it will be ready to fully re-review, will let you know.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: Creditbureau phase 3 Integration

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-670226448


   @vorburger, yes there is an open JIRA issue for this PR. https://issues.apache.org/jira/browse/FINERACT-734


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] nikpawar89 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
nikpawar89 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r475149812



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {

Review comment:
       mark private

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")

Review comment:
       why do we need @CacheEvict

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String Name = null;
+        String Gender = null;
+        nrcId = searchId;
+        String Address = null;
+
+        this.context.authenticatedUser();
+
+        final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+        if (credittokendata != null) {
+            userName = credittokendata.getUserName();
+            password = credittokendata.getPassword();
+            subscriptionId = credittokendata.getSubscriptionId();
+            subscriptionKey = credittokendata.getSubscriptionKey();
+
+            // validation required, incase when configuration is not stored in database while fetching data.
+        } else {
+
+            String configJson = "{ 'userName':'" + userName + "','password':'" + password + "','subscriptionId':'" + subscriptionId
+                    + "','subscriptionKey':'" + subscriptionKey + "'}";
+
+            this.fromApiJsonDeserializer.validateForUsingTokenConfig(configJson);
+        }
+
+        CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+        LOG.info("creditbureautoken : {} ", creditbureautoken);
+
+        // check the expiry date of the previous token.
+        if (creditbureautoken != null) {
+            Date current = new Date();
+            Date getExpiryDate = creditbureautoken.getTokenExpiryDate();
+
+            LOG.info("current date : {} ", current);
+            LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+            if (getExpiryDate.before(current)) {
+                LOG.info("The token is expired");
+                this.tokenRepository.delete(creditbureautoken);
+                creditbureautoken = null;
+            }
+        }
+        // storing token if it is valid token(not expired)
+        if (creditbureautoken != null) {
+            token = creditbureautoken.getCurrentToken();
+        }
+
+        // if token is not available or previous token is expired then create a new token
+        if (creditbureautoken == null) {
+
+            // using common http connection method for creating token
+            process = "token";
+            this.httpConnectionMethod();
+
+            JsonObject tokenObject = JsonParser.parseString(result).getAsJsonObject();
+            String expiresextra = tokenObject.get(".expires").toString();
+            String expires = expiresextra.substring(1, expiresextra.length() - 1);
+            DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+            try {
+                Date getExpiryDate = dateformat.parse(expires);
+                LOG.info("The expirydate {}", getExpiryDate);
+            } catch (ParseException Ex) {
+                LOG.error("Error occured.", Ex);
+            }
+
+            // created token will be storing it into database
+            final CommandWrapper wrapper = new CommandWrapperBuilder().withJson(result).build();
+            final String json = wrapper.getJson();
+            result = null;
+            JsonCommand apicommand = null;
+            boolean isApprovedByChecker = false;
+            final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
+
+            apicommand = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(),
+                    wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getSavingsId(),
+                    wrapper.getTransactionId(), wrapper.getHref(), wrapper.getProductId(), wrapper.getCreditBureauId(),
+                    wrapper.getOrganisationCreditBureauId());
+
+            this.fromApiJsonDeserializer.validateForCreate(apicommand.json());
+
+            final CreditBureauToken generatedtoken = CreditBureauToken.fromJson(apicommand);
+
+            // saved new token
+            this.tokenRepository.save(generatedtoken);
+
+            // fetched
+            creditbureautoken = this.tokenRepository.getToken();
+            token = creditbureautoken.getCurrentToken();
+
+            // at this stage token is available for all cases i.e.(deleted expired token and saved new token)
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        process = "NRC";
+        this.httpConnectionMethod();
+
+        // after fetching the data from httpconnection it will be come back here for fetching UniqueID from data
+        if (process.equals("NRC")) {
+
+            // to fetch the Unique ID from Result
+            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();
+            JsonArray jArray = jsonObject.getAsJsonArray("Data");
+            JsonObject jobject = jArray.get(0).getAsJsonObject();
+            String uniqueIdString = jobject.get("UniqueID").toString();
+
+            // cleaned the uniqueID value. Example id: "123" to 123
+            String TrimUniqueId = uniqueIdString.substring(1, uniqueIdString.length() - 1);
+
+            // unique ID is stored
+            uniqueID = Long.parseLong(TrimUniqueId);
+
+            // will use "CREDITREPORT" part of code from common http method to fetch creditreport based on UniqueID
+            process = "CREDITREPORT";
+            this.httpConnectionMethod();
+
+        }
+
+        // after fetching the data from httpconnection it will be come back here to assign data(result) to generic
+        // creditreportdata object
+
+        JsonObject reportObject = JsonParser.parseString(result).getAsJsonObject();
+
+        JsonObject borrowerInfo = null;
+        JsonObject CreditScore = null;
+        JsonArray ActiveLoans = null;
+        JsonArray PaidLoans = null;
+
+        // Credit Reports Stored into Generic CreditReportData
+        JsonObject data = null;
+        JsonElement element = reportObject.get("Data");
+
+        if (!(element instanceof JsonNull)) { // NOTE : "element instanceof JsonNull" is for handling empty values (and

Review comment:
       is there a better way to do this null check?
   using instanceof is not considered as good practice:
   https://dzone.com/articles/instanceof-considered-harmful

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;

Review comment:
       please keep the scope of variables as small as possible. Applies to all the variables below

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");

Review comment:
       url should be part of configuration and should not be hard coded.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);

Review comment:
       here as well

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);

Review comment:
       same here

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {

Review comment:
       I liked this approach, its just that make process as parameter to this method.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String Name = null;
+        String Gender = null;
+        nrcId = searchId;
+        String Address = null;
+
+        this.context.authenticatedUser();
+
+        final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+        if (credittokendata != null) {
+            userName = credittokendata.getUserName();
+            password = credittokendata.getPassword();
+            subscriptionId = credittokendata.getSubscriptionId();
+            subscriptionKey = credittokendata.getSubscriptionKey();
+
+            // validation required, incase when configuration is not stored in database while fetching data.
+        } else {
+
+            String configJson = "{ 'userName':'" + userName + "','password':'" + password + "','subscriptionId':'" + subscriptionId
+                    + "','subscriptionKey':'" + subscriptionKey + "'}";
+
+            this.fromApiJsonDeserializer.validateForUsingTokenConfig(configJson);
+        }
+
+        CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+        LOG.info("creditbureautoken : {} ", creditbureautoken);
+
+        // check the expiry date of the previous token.
+        if (creditbureautoken != null) {
+            Date current = new Date();
+            Date getExpiryDate = creditbureautoken.getTokenExpiryDate();
+
+            LOG.info("current date : {} ", current);
+            LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+            if (getExpiryDate.before(current)) {
+                LOG.info("The token is expired");
+                this.tokenRepository.delete(creditbureautoken);
+                creditbureautoken = null;
+            }
+        }
+        // storing token if it is valid token(not expired)
+        if (creditbureautoken != null) {
+            token = creditbureautoken.getCurrentToken();
+        }
+
+        // if token is not available or previous token is expired then create a new token
+        if (creditbureautoken == null) {
+
+            // using common http connection method for creating token
+            process = "token";
+            this.httpConnectionMethod();
+
+            JsonObject tokenObject = JsonParser.parseString(result).getAsJsonObject();
+            String expiresextra = tokenObject.get(".expires").toString();
+            String expires = expiresextra.substring(1, expiresextra.length() - 1);
+            DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       keep it simple : SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,121 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauToken.class);
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String accessToken;
+
+    @Column(name = "token_type")
+    private String tokenType;
+
+    @Column(name = "expires_in")
+    private String expiresIn;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")
+    private Date expires;
+
+    public CreditBureauToken(String userName, String accessToken, String tokenType, String expiresIn, String issued, Date expires) {
+        this.userName = userName;
+        this.accessToken = accessToken;
+        this.tokenType = tokenType;
+        this.expiresIn = expiresIn;
+        this.issued = issued;
+        this.expires = expires;
+    }
+
+    public CreditBureauToken() {
+        this.userName = null;
+        this.accessToken = null;
+        this.tokenType = null;
+        this.expiresIn = null;
+        this.issued = null;
+        this.expires = null;
+    }
+
+    public static CreditBureauToken fromJson(final JsonCommand command) {
+        final String userName = command.stringValueOfParameterNamed("userName");
+        final String accessToken = command.stringValueOfParameterNamed("access_token");
+        final String tokenType = command.stringValueOfParameterNamed("token_type");
+        final String expiresIn = command.stringValueOfParameterNamed("expires_in");
+        final String issued = command.stringValueOfParameterNamed(".issued");
+        final String expiry = command.stringValueOfParameterNamed(".expires");
+
+        LOG.info("Expiry {}", expiry);
+
+        DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {

Review comment:
       Try resources could be helpful here, please check out the java doc.

##########
File path: fineract-provider/config/swagger/fineract-input.yaml
##########
@@ -0,0 +1,37 @@
+openapi: 3.0.3

Review comment:
       did you intend to add this File in commit?

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();

Review comment:
       I think result should be the return type of this method.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String Name = null;
+        String Gender = null;
+        nrcId = searchId;
+        String Address = null;
+
+        this.context.authenticatedUser();
+
+        final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+        if (credittokendata != null) {
+            userName = credittokendata.getUserName();
+            password = credittokendata.getPassword();
+            subscriptionId = credittokendata.getSubscriptionId();
+            subscriptionKey = credittokendata.getSubscriptionKey();
+
+            // validation required, incase when configuration is not stored in database while fetching data.
+        } else {
+
+            String configJson = "{ 'userName':'" + userName + "','password':'" + password + "','subscriptionId':'" + subscriptionId
+                    + "','subscriptionKey':'" + subscriptionKey + "'}";
+
+            this.fromApiJsonDeserializer.validateForUsingTokenConfig(configJson);
+        }
+
+        CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+        LOG.info("creditbureautoken : {} ", creditbureautoken);
+
+        // check the expiry date of the previous token.
+        if (creditbureautoken != null) {
+            Date current = new Date();
+            Date getExpiryDate = creditbureautoken.getTokenExpiryDate();
+
+            LOG.info("current date : {} ", current);
+            LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+            if (getExpiryDate.before(current)) {
+                LOG.info("The token is expired");
+                this.tokenRepository.delete(creditbureautoken);
+                creditbureautoken = null;
+            }
+        }
+        // storing token if it is valid token(not expired)
+        if (creditbureautoken != null) {
+            token = creditbureautoken.getCurrentToken();
+        }
+
+        // if token is not available or previous token is expired then create a new token
+        if (creditbureautoken == null) {
+
+            // using common http connection method for creating token
+            process = "token";
+            this.httpConnectionMethod();
+
+            JsonObject tokenObject = JsonParser.parseString(result).getAsJsonObject();
+            String expiresextra = tokenObject.get(".expires").toString();
+            String expires = expiresextra.substring(1, expiresextra.length() - 1);
+            DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);
+            try {
+                Date getExpiryDate = dateformat.parse(expires);
+                LOG.info("The expirydate {}", getExpiryDate);
+            } catch (ParseException Ex) {
+                LOG.error("Error occured.", Ex);
+            }
+
+            // created token will be storing it into database
+            final CommandWrapper wrapper = new CommandWrapperBuilder().withJson(result).build();
+            final String json = wrapper.getJson();
+            result = null;
+            JsonCommand apicommand = null;
+            boolean isApprovedByChecker = false;
+            final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
+
+            apicommand = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(),
+                    wrapper.getSubentityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getSavingsId(),
+                    wrapper.getTransactionId(), wrapper.getHref(), wrapper.getProductId(), wrapper.getCreditBureauId(),
+                    wrapper.getOrganisationCreditBureauId());
+
+            this.fromApiJsonDeserializer.validateForCreate(apicommand.json());
+
+            final CreditBureauToken generatedtoken = CreditBureauToken.fromJson(apicommand);
+
+            // saved new token
+            this.tokenRepository.save(generatedtoken);
+
+            // fetched
+            creditbureautoken = this.tokenRepository.getToken();
+            token = creditbureautoken.getCurrentToken();
+
+            // at this stage token is available for all cases i.e.(deleted expired token and saved new token)
+        }
+
+        // will use only "NRC" part of code from common http method to get data based on nrc
+        process = "NRC";
+        this.httpConnectionMethod();
+
+        // after fetching the data from httpconnection it will be come back here for fetching UniqueID from data
+        if (process.equals("NRC")) {
+
+            // to fetch the Unique ID from Result
+            JsonObject jsonObject = JsonParser.parseString(result).getAsJsonObject();

Review comment:
       Get result as return type of httpConnectionMethod() and validate if it is null.
   Processing it directly is a potential NPE.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauTokenWritePlatformServiceImpl.java
##########
@@ -0,0 +1,178 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonElement;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepository;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauTokenWritePlatformServiceImpl implements CreditBureauTokenWritePlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauTokenWritePlatformServiceImpl.class);
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final CreditBureauTokenRepository creditBureauTokenRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+    private final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final CreditBureauToken creditBureauToken;
+    private final TokenDataRepository tokendatRepository;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private static String tokenstr;
+    private final JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    public CreditBureauTokenWritePlatformServiceImpl(final PlatformSecurityContext context,
+            final CreditBureauTokenRepository creditBureauTokenRepository, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository, final TokenDataRepository tokendatRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer, final FromJsonHelper fromApiJsonHelper,
+            final CreditBureauTokenReadPlatformService readPlatformServiceCreditBureauToken,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, final CreditBureauToken creditBureauToken,
+            final RoutingDataSource dataSource) {
+        this.context = context;
+        this.creditBureauTokenRepository = creditBureauTokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.tokenRepository = tokenRepository;
+        this.tokendatRepository = tokendatRepository;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.readPlatformServiceCreditBureauToken = readPlatformServiceCreditBureauToken;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.creditBureauToken = creditBureauToken;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "credittoken", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CommandProcessingResult createCreditBureauToken(JsonCommand command) {
+        try {
+            this.context.authenticatedUser();
+
+            // fetch the token credentials for using it in header
+            final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+            String userName = credittokendata.getUserName();
+            String password = credittokendata.getPassword();
+            String subscriptionId = credittokendata.getSubscriptionId();
+            String subscriptionKey = credittokendata.getSubscriptionKey();
+
+            final String POST_PARAMS = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName
+                    + "&\r\n" + "password=" + password + "&\r\n";
+
+            URL obj = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+            String readLine = null;
+
+            HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
+            postConnection.setRequestMethod("POST");

Review comment:
       i don't see a method.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492519326



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r548882174



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/api/CreditBureauIntegrationAPI.java
##########
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.api;
+
+import com.google.gson.Gson;
+import io.swagger.v3.oas.annotations.Parameter;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportReadPlatformService;
+import org.apache.fineract.infrastructure.creditbureau.service.CreditReportWritePlatformService;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Path("/creditBureauIntegration")
+@Component
+@Scope("singleton")
+public class CreditBureauIntegrationAPI {
+
+    private static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "creditBureauId", "nrc", "creditReport"));
+
+    private final PlatformSecurityContext context;
+    private final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer;
+    private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+    private final ApiRequestParameterHelper apiRequestParameterHelper;
+    private final CreditReportWritePlatformService creditReportWritePlatformService;
+    private final CreditReportReadPlatformService creditReportReadPlatformService;
+    private final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer;
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauIntegrationAPI.class);
+
+    @Autowired
+    public CreditBureauIntegrationAPI(final PlatformSecurityContext context,
+            final DefaultToApiJsonSerializer<CreditReportData> toCreditReportApiJsonSerializer,
+            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
+            final ApiRequestParameterHelper apiRequestParameterHelper,
+            final CreditReportWritePlatformService creditReportWritePlatformService,
+            final CreditReportReadPlatformService creditReportReadPlatformService,
+            final DefaultToApiJsonSerializer<CreditReportData> toApiJsonSerializer) {
+        this.context = context;
+        this.toCreditReportApiJsonSerializer = toCreditReportApiJsonSerializer;
+        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+        this.apiRequestParameterHelper = apiRequestParameterHelper;
+        this.creditReportWritePlatformService = creditReportWritePlatformService;
+        this.creditReportReadPlatformService = creditReportReadPlatformService;
+        this.toApiJsonSerializer = toApiJsonSerializer;
+
+    }
+
+    @POST
+    @Path("creditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String postCreditReport(@Context final UriInfo uriInfo, @RequestParam("params") final Map<String, Object> params) {
+
+        Gson gson = new Gson();
+        final String json = gson.toJson(params);
+        final CommandWrapper commandRequest = new CommandWrapperBuilder().getCreditReport().withJson(json).build();
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // saves fetched-creditreport into database
+    @POST
+    @Path("saveCreditReport")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String saveCreditReport(@Parameter(hidden = true) final String apiRequestBodyAsJson,
+            @QueryParam("creditBureauId") @Parameter(description = "creditBureauId") final Long creditBureauId,
+            @QueryParam("creditReportNumber") @Parameter(description = "creditReportNumber") final String creditReportNumber) {
+
+        final CommandWrapper commandRequest = new CommandWrapperBuilder() //
+                .saveCreditReport(creditBureauId, creditReportNumber) // creditReportNumber is a NRC number for
+                                                                      // Thitsawork
+                .withJson(apiRequestBodyAsJson) // apiRequestBodyAsJson is a creditReport
+                .build(); //
+
+        final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+        return this.toCreditReportApiJsonSerializer.serialize(result);
+
+    }
+
+    // fetch saved creditReports(NRC) from DB by creditBureauId, to select for downloading and deleting the reports
+    @GET
+    @Path("creditReport/{creditBureauId}")

Review comment:
       To get the details of the credit report specifically of that credit bureau, we are using creditBureauId, It fetches the credit report details like (national Id/NRC) to check whether that specific credit report has been stored or not in the database.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on a change in pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on a change in pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#discussion_r492518373



##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {

Review comment:
       Kept it public to make it accessible for test case

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")

Review comment:
       Removed CacheEvict

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();
+
+            } else {
+                LOG.info("Request is Invalid");
+            }
+
+        } catch (IOException e) {
+            LOG.error("Error occured.", e);
+        }
+    }
+
+    @SuppressWarnings({ "CatchAndPrintStackTrace", "DefaultCharset" })
+    @Override
+    @Transactional
+    @CacheEvict(value = "searchreport", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat('cv')")
+    public CreditReportData retrieveAllSearchReport(final String searchId) {
+        String Name = null;
+        String Gender = null;
+        nrcId = searchId;
+        String Address = null;
+
+        this.context.authenticatedUser();
+
+        final CreditBureauTokenCredential credittokendata = this.tokenDataRepository.getTokenCredential();
+
+        if (credittokendata != null) {
+            userName = credittokendata.getUserName();
+            password = credittokendata.getPassword();
+            subscriptionId = credittokendata.getSubscriptionId();
+            subscriptionKey = credittokendata.getSubscriptionKey();
+
+            // validation required, incase when configuration is not stored in database while fetching data.
+        } else {
+
+            String configJson = "{ 'userName':'" + userName + "','password':'" + password + "','subscriptionId':'" + subscriptionId
+                    + "','subscriptionKey':'" + subscriptionKey + "'}";
+
+            this.fromApiJsonDeserializer.validateForUsingTokenConfig(configJson);
+        }
+
+        CreditBureauToken creditbureautoken = this.tokenRepository.getToken();
+        LOG.info("creditbureautoken : {} ", creditbureautoken);
+
+        // check the expiry date of the previous token.
+        if (creditbureautoken != null) {
+            Date current = new Date();
+            Date getExpiryDate = creditbureautoken.getTokenExpiryDate();
+
+            LOG.info("current date : {} ", current);
+            LOG.info("getExpiryDate : {} ", getExpiryDate);
+
+            if (getExpiryDate.before(current)) {
+                LOG.info("The token is expired");
+                this.tokenRepository.delete(creditbureautoken);
+                creditbureautoken = null;
+            }
+        }
+        // storing token if it is valid token(not expired)
+        if (creditbureautoken != null) {
+            token = creditbureautoken.getCurrentToken();
+        }
+
+        // if token is not available or previous token is expired then create a new token
+        if (creditbureautoken == null) {
+
+            // using common http connection method for creating token
+            process = "token";
+            this.httpConnectionMethod();
+
+            JsonObject tokenObject = JsonParser.parseString(result).getAsJsonObject();
+            String expiresextra = tokenObject.get(".expires").toString();
+            String expires = expiresextra.substring(1, expiresextra.length() - 1);
+            DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
##########
@@ -0,0 +1,121 @@
+package org.apache.fineract.infrastructure.creditbureau.domain;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@Entity
+@Table(name = "m_creditbureau_token")
+public class CreditBureauToken extends AbstractPersistableCustom {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauToken.class);
+
+    @Column(name = "username")
+    private String userName;
+
+    @Column(name = "token")
+    private String accessToken;
+
+    @Column(name = "token_type")
+    private String tokenType;
+
+    @Column(name = "expires_in")
+    private String expiresIn;
+
+    @Column(name = "issued")
+    private String issued;
+
+    @Column(name = "expires")
+    private Date expires;
+
+    public CreditBureauToken(String userName, String accessToken, String tokenType, String expiresIn, String issued, Date expires) {
+        this.userName = userName;
+        this.accessToken = accessToken;
+        this.tokenType = tokenType;
+        this.expiresIn = expiresIn;
+        this.issued = issued;
+        this.expires = expires;
+    }
+
+    public CreditBureauToken() {
+        this.userName = null;
+        this.accessToken = null;
+        this.tokenType = null;
+        this.expiresIn = null;
+        this.issued = null;
+        this.expires = null;
+    }
+
+    public static CreditBureauToken fromJson(final JsonCommand command) {
+        final String userName = command.stringValueOfParameterNamed("userName");
+        final String accessToken = command.stringValueOfParameterNamed("access_token");
+        final String tokenType = command.stringValueOfParameterNamed("token_type");
+        final String expiresIn = command.stringValueOfParameterNamed("expires_in");
+        final String issued = command.stringValueOfParameterNamed(".issued");
+        final String expiry = command.stringValueOfParameterNamed(".expires");
+
+        LOG.info("Expiry {}", expiry);
+
+        DateFormat dateformat = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss zzz", Locale.ENGLISH);

Review comment:
       Comment Addressed.

##########
File path: fineract-provider/config/swagger/fineract-input.yaml
##########
@@ -0,0 +1,37 @@
+openapi: 3.0.3

Review comment:
       No, So it has been removed.

##########
File path: fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReportsReadPlatformServiceImpl.java
##########
@@ -0,0 +1,347 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fineract.infrastructure.creditbureau.service;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.creditbureau.data.CreditReportData;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauToken;
+import org.apache.fineract.infrastructure.creditbureau.domain.CreditBureauTokenCredential;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenDataRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWrapper;
+import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class CreditBureauReportsReadPlatformServiceImpl implements CreditBureauReportsReadPlatformService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CreditBureauReportsReadPlatformServiceImpl.class);
+    private final JdbcTemplate jdbcTemplate;
+    private final PlatformSecurityContext context;
+    private final FromJsonHelper fromApiJsonHelper;
+    private final TokenRepositoryWrapper tokenRepository;
+    private final TokenDataRepositoryWrapper tokenDataRepository;
+    private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
+
+    @Autowired
+    public CreditBureauReportsReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepository,
+            final TokenDataRepositoryWrapper tokenDataRepository,
+            final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
+        this.context = context;
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.tokenRepository = tokenRepository;
+        this.tokenDataRepository = tokenDataRepository;
+        this.fromApiJsonHelper = fromApiJsonHelper;
+        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
+    }
+
+    String nrcId = null;
+    Long uniqueID = 0L;
+    String userName = "";
+    String password = "";
+    String subscriptionId = "";
+    String subscriptionKey = "";
+
+    StringBuilder response = new StringBuilder();
+    HttpURLConnection postConnection;
+    String tokenDate;
+    String token = null;
+    String process = null;
+    String result = null;
+
+    public void httpConnectionMethod() {
+        try {
+            String readLine = null;
+            String post_params = null;
+
+            if (process.equals("token")) {
+                LOG.info("-----creating new token-----");
+                post_params = "\n" + "BODY=x-www-form-urlencoded&\r\n" + "grant_type=password&\r\n" + "userName=" + userName + "&\r\n"
+                        + "password=" + password + "&\r\n";
+
+                URL tokenurl = new URL("https://mmcix.azure-api.net/qa/20200324/Token");
+                readLine = null;
+                postConnection = (HttpURLConnection) tokenurl.openConnection();
+                postConnection.setRequestMethod("POST");
+
+            } else if (process.equals("NRC")) {
+                // Search Methods
+                LOG.info("-----Search by NRC-----");
+                post_params = "BODY=x-www-form-urlencoded&nrc=" + nrcId + "&";
+
+                URL NrcURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Search/SimpleSearch?nrc=" + nrcId);
+                postConnection = (HttpURLConnection) NrcURL.openConnection();
+                postConnection.setRequestMethod("POST");
+            }
+
+            else if (process.equals("CREDITREPORT")) {
+                LOG.info("-----Search by CREDIT_REPORT-----");
+                URL CreditReportURL = new URL("https://mmcix.azure-api.net/qa/20200324/api/Dashboard/GetCreditReport?uniqueId=" + uniqueID);
+                postConnection = (HttpURLConnection) CreditReportURL.openConnection();
+                postConnection.setRequestMethod("GET");
+
+            }
+
+            // common set of headers
+            postConnection.setRequestProperty("mcix-subscription-key", subscriptionKey);
+            postConnection.setRequestProperty("mcix-subscription-id", subscriptionId);
+            postConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
+            // token header not used when creating token i.e. when token will be null
+            if (token != null) {
+                postConnection.setRequestProperty("Authorization", "Bearer " + token);
+            }
+
+            // this set of code only required for fetching uniqueID from Nrc fetched data (POST-SimpleSearch)
+            if (process.equals("NRC") || process.equals("token")) {
+                LOG.info("-----NRC & CREDITREPORT -----");
+                postConnection.setDoOutput(true);
+                OutputStream os = postConnection.getOutputStream();
+                os.write(post_params.getBytes(StandardCharsets.UTF_8));
+                os.flush();
+                os.close();
+
+            }
+
+            // common part of code in http connection method
+            int responseCode = postConnection.getResponseCode();
+
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                response = new StringBuilder();
+
+                LOG.info("----- RESPONSE OK-----");
+                BufferedReader in = new BufferedReader(new InputStreamReader(postConnection.getInputStream(), StandardCharsets.UTF_8));
+                while ((readLine = in.readLine()) != null) {
+                    response.append(readLine);
+                }
+                in.close();
+                result = response.toString();

Review comment:
       Comment Addressed.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] rrpawar96 commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
rrpawar96 commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-698947671


   @vorburger, yes the PR is ready to get reviewed.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [fineract] github-actions[bot] commented on pull request #1235: FINERACT-734 Creditbureau-Integration-phase3

Posted by GitBox <gi...@apache.org>.
github-actions[bot] commented on pull request #1235:
URL: https://github.com/apache/fineract/pull/1235#issuecomment-696453111


   This pull request seems to be stale.  Are you still planning to work on it?  We will automatically close it in 30 days.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org