0

I have the following classes:

public class AccountDetail {
    private String accountNumber;
    private Date effectiveDate;
    private String status;
    // a bunch of other properties
}

public class AccountDetailWithAlerts extends AccountDetail {
    private LowMediumAlerts alerts;
}

public class AccountsAndAlerts {
    private List<AccountDetailWithAlerts> accounts;
    private HighCustomerAccountAlerts accountAlerts;
    // getters and setters
}

public class CustomerAndAccountAlerts {
    private List<AlertMessage> customerAlerts;
    private List<AccountAlertMessages> accountAlerts;
}

public Class CompanyResponse<T> {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T response;
    // other things that aren't relevant
}

I have a controller, AccountsController, that does a @GetMapping and has a ResponseEntity method:

public ResponseEntity<CompanyResponse<AccountsAndAlerts> getAccountDetails {
    @RequestParam MultiValueMap<String, String> queryParms,
    // some @ApiParams for client-header, end-user-id & accountNumber
    String accountId = queryParms.getFirst("accountId");
    // setting RestHeaders, contentType

    CompanyResponse<AccountsAndAlerts> response = accountDetailService.getAccountsWithAlerts(restHeaders, accountNumber, queryParms, accountId);
    return new ResponseEntity<CompanyResponse<AccountsAndAlerts>>(response, headers, HttpStatus.valueOf(response.getStatus()));
}

Here is the method in accountDetailService:

public CompanyResponse<AccountsAndAlerts> getAccountsWithAlerts(RestHeaders restHeaders, String accountNumber, MultiValueMap<String, String> queryParms, String accountId) throws... {
    CompanyResponse<AccountsAndAlerts> newResponse = new CompanyResponse<AccountsAndAlerts>();
    try {
        CompletableFuture<List<AccountDetailWithAlerts>> accountsFuture = accountDetails.getAccounts(newResponse, restHeaders, accountNumber, queryParms);
        CompletableFuture<CustomerAndAccountAlerts> alertsFuture = accountDetails.getAlerts(newResponse, restHeaders, accountId);

        accountsFuture.thenAcceptBoth(alertsFuture, (s1, s2) -> newResponse.setResponse(getResponse(s1, s2))).get();
    } catch {
        // catch code
    }
    return newResponse;
}

Finally, the getAccounts method in AccountDetails:

public CompletableFuture<List<AccountDetailWithAlerts>> getAccounts(CompanyResponse<AccountsAndAlerts> newResponse, RestHeaders restHeaders, String accountNumber, MultiValueMap<String, String> queryParms) throws ... {
    // this has the restTemplate and the .supplyAsync()

}

What I need to do is create a new ResponseEntityMethod in the Controller:

public ResponseEntity<CompanyResponse<AccountDetail> getCertainAccountDetails

I have put in a return of that type, and I am attempting to create a new method in the accountDetailService, getCertainAccounts().

The problem is trying to set this all up without creating a whole other CompletableFuture method with an invoke and supplyAsync() and restTemplate and such.

It appears that I still need to call getAccounts(), but then I have to somewhere along this line downcast the AccountDetailWithMessages to AccountDetail. I don't know if I can somehow downcast CompletableFuture<List<AccountDetailWithAlerts>> to CompletableFuture<List<AccountDetail>> or how to do it, or if I really need to downcast CompanyResponse<AccountsAndAlerts> or how to do that.

Can anyone help?

PS. I changed the names of everything to protect my Company's code. If you see errors in methods or names or anything, please be assured that is not an issue and is just the result of my typing things out instead of copying and pasting. The only issue is how to do the downcasting.

Thanks!

PPS. In case it wasn't clear, with my new method and code I do not want to get the alerts. I am trying to get account details only without alerts.

Didier L
  • 18,905
  • 10
  • 61
  • 103
apex2022
  • 777
  • 2
  • 8
  • 28
  • The text mentions `AccountDetailWithMessages` whereas the code uses `AccountDetailWithAlerts` – as I wasn’t sure I didn’t change it. – Didier L Jan 27 '22 at 19:37
  • Note that even if the method returns a `ResponseEntity>`, if the real object is an `AccountDetailWithAlerts` the HTTP response will still contain all its fields, including the alerts, so if there is no other reason to use `AccountDetail` there, it would seem simpler to just declare the response with `AccountDetailWithAlerts`. – Didier L Jan 27 '22 at 19:39
  • What’s really missing in the question though is what problem do you have exactly with the conversion – you have a `CompletableFuture>` that you transform into a `CompanyResponse`, so what issue do you have creating that `new CompanyResponse()`? I fear that you didn’t test the code in your question when trying to make it a true [mre], and it is too different from your actual code. – Didier L Jan 27 '22 at 19:48
  • Side note, concerning your `supplyAsync()` calls, you should look towards Spring `@Async`. Maybe [this question](https://stackoverflow.com/q/44685187/525036) can help. – Didier L Jan 27 '22 at 19:50

0 Answers0