-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lcam 976 call stateless from stateful #395
base: main
Are you sure you want to change the base?
Conversation
1685c3c
to
c872ebf
Compare
14aa043
to
38afcf8
Compare
38afcf8
to
c18ba55
Compare
e575bd7
to
1d4b64e
Compare
Kudos, SonarCloud Quality Gate passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to have a wider conversation about this work and whether it's really necessary. It doesn't seem to enable Phase 2 in any way and there are serious risks to our production services.
this.assessmentCompletionService = assessmentCompletionService; | ||
this.meansAssessmentBuilder = meansAssessmentBuilder; | ||
this.assessmentCriteriaDetailService = assessmentCriteriaDetailService; | ||
this.incomeEvidenceService = incomeEvidenceService; | ||
this.crownCourtEligibilityService = crownCourtEligibilityService; | ||
|
||
statelessAssessmentService = new StatelessAssessmentService(assessmentCriteriaService, meansAssessmentServiceFactory, fullAssessmentAvailabilityService); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should follow the pattern we've used for the other dependent classes. We shouldn't be initialising this ourselves when Spring can do it for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose this route as the current tests are based on mocking the dependencies. If this change altered the dependencies, it would alter the tests too which felt like a risk
requestDTO.getCaseType(), | ||
requestDTO.getMagCourtOutcome(), | ||
incomesFromSectionSummaries(requestDTO.getSectionSummaries(), assessmentCriteria), | ||
requestDTO.getNewWorkReason()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If formatting a method call like this, please place the );
on a new line, I think it really helps the readability.
AssessmentCriteriaEntity assessmentCriteria = assessmentCriteriaService.getAssessmentCriteria( | ||
assessmentDate, requestDTO.getHasPartner(), requestDTO.getPartnerContraryInterest()); | ||
|
||
BigDecimal summariesTotal = calculateSummariesTotal(requestDTO, assessmentCriteria); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The answer is yes, the side effects from this method are important. See my comments in the StatelessMeansAssessment
class for ideas on how to mitigate this.
private StatelessInitialResult initialResult(@NotNull Assessment assessment, | ||
@NotNull BigDecimal totalIncome, | ||
@NotNull Map<AgeRange, Integer> childGroupings) { | ||
public StatelessInitialResult initialResult(@NotNull Map<AgeRange, Integer> childGroupings, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove the incomes parameter here and the outgoings one in the fullResult
method. Instead, the methods should accept a BigDecimal
total. This way, the MeansAssessmentService
can call calculateSummariesTotal
and then simply pass in the overall total. Then it's just a case of moving the calcIncomeTotals
and calcOutgoingTotals
to the execute method.
final var children = mapChildGroupings(childGroupings, criteriaEntry.getAssessmentCriteriaChildWeightings()); | ||
|
||
final var totalIncome = calcIncomeTotals(criteriaEntry, caseType, incomes); | ||
final var service = meansAssessmentServiceFactory.getService(AssessmentType.INIT); | ||
|
||
// assessmentStatus has to be set 'COMPLETE' otherwise the return value is null | ||
final MeansAssessmentRequestDTO requestDTO = MeansAssessmentRequestDTO | ||
.builder() | ||
.childWeightings(children) | ||
.assessmentStatus(CurrentStatus.COMPLETE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a problem. It's perfectly valid for an assessment to be set as 'Incomplete' in MAAT
.
requestDTO.setEligibilityCheckRequired(crownCourtEligibilityService.isEligibilityCheckRequired(requestDTO)); | ||
MeansAssessmentDTO completedAssessment; | ||
boolean fullAssessmentAvailable; | ||
final var childGroupings = childGroupingsFromChildWeightings(requestDTO.getChildWeightings()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to convert this when we're just going to do the reverse in the first line of initResult
& fullResult
? I'd update the methods to take the child weightings instead.
public StatelessFullResult fullResult(Map<AgeRange, Integer> childGroupings, | ||
AssessmentCriteriaEntity criteriaEntry, | ||
boolean eligibilityCheckRequired, | ||
CaseType caseType, | ||
List<Outgoing> outgoings, | ||
BigDecimal totalIncome) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, this is too many parameters, however, there is a degree of preference involved. That said, is there a way we could reduce this? For example, moving the mapChildGroupings
call? A lot are being passed in just to build the MeansAssessmentRequestDTO
, can't we just build this in the execute method instead?
|
||
class MaatToStatelessDataAdapterTest { | ||
|
||
private static final AssessmentCriteriaEntity assessmentCriteria = TestModelDataBuilder.getAssessmentCriteriaEntityWithDetails(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SonarCloud report shows we don't have full coverage of this class.
@Mhowell494 it was a while ago now, but this was a key next step agreed when we met on 18th August. The issue is that the MeansAssessmentService 'MAS' used by MAAT production makes several deep calls into what is now considered the 'stateless business logic', bypassing the new StatelessAssessmentService 'SMAS'. As discussed, it seemed a bit risky having two different ways to call methods assessmentCriteriaSevice.getAssessmentCriteria, calculateSummariesTotal, Full/InitMeansAssesmsnetService.execute and FullAssessmentAvailabilityService. Better to get rid of that duplication and get MAS to call SMAS. Yes it forces the issue of whether the new SMAS is good enough for MAAT production. Better to do that sooner rather than later. And the development of SMAS has been reviewed and approved by your team, so hopefully not far off.
The PR description raises concerns about some untested side-effects and we'd appreciate your views on a practical way forward to address. Very happy to discuss this all on a all if that helps |
Thanks @davidread, I think Jude has put a meeting in to discuss tomorrow. I do recall the discussion on the 18th and believe I raised concerns at the time with the outcome being that we agreed to explore the idea, but as far as I'm aware there's been no discussion since. I don't believe these changes make Phase 2 any easier to deliver and it's all going to have to be refactored in the future anyway when we update the calculation logic to work with the stateless schema objects. The only thing that's really been eliminated is the call to the I did suggest a solution to the side effects problem in my comments above, but it would mean changing several method signatures or duplicated calls to From my point of view, the underlying logic that deals with the calculations is shared between both implementations and we're confident that's it's robust. So I think for me that small amount of duplication is acceptable in the short term when weighed against the risks of introducing bugs, for what I feel is a fairly limited benefit. |
https://dsdmoj.atlassian.net/browse/LCAM-976
Call stateless service (SMAS) from stateful service (MAS). This includes a translation layer between stateful integer ids and their 'more friendly' code-based ids (so EMP_INC rather than 135). This will help support future work where CMA (or something similar) invokes the eligibility platform via an HTTP API call rather than a Java call (as now)
Note to reviewer: I think this PR might remove some side-effects from the API - specifically the calculation of the partnerAnnualTotal and applicantAnnualTotal fields (but there may be others). Is there some way we can determine if these are required? There are no tests that assert this behaviour.
Checklist
Before you ask people to review this PR:
./gradlew test
git rebase main
.