Skip to content
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

New formula for Adoption Plan Confidence #73

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
16 changes: 15 additions & 1 deletion .github/scripts/check_api.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/sh
set -e
set -x # print commands executed
set -e # exit immediatly if any command fails

# Usage : check_api.sh api_ip keycloak_api , both arguments optional defaulted to $(minikube ip)
# ./check_api.sh localhost:8085 localhost:8180
Expand Down Expand Up @@ -266,4 +267,17 @@ req_identified_risks=$(curl -X POST "http://$api_ip/pathfinder/assessments/risks
-H 'Content-Type: application/json' -s -w "%{http_code}" -o /dev/null)
test "$(echo $req_identified_risks)" = "400"


echo
echo
echo "19 >>> Checking the confidence of assessments"
confidence=$(curl -X POST "http://$api_ip/pathfinder/assessments/confidence" -H 'Accept: application/json' \
-H "Authorization: Bearer $access_token" \
-d "[{\"applicationId\":100} , {\"applicationId\": $applicationTarget}]" \
-H 'Content-Type: application/json' )
echo $confidence | grep "\"assessmentId\":$assessmentCopiedId"
echo $confidence | grep "\"confidence\":"
echo $confidence | grep "\"applicationId\":$applicationTarget"


echo " +++++ API CHECK SUCCESSFUL ++++++"
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.tackle.pathfinder.controllers;

import io.tackle.pathfinder.dto.AdoptionCandidateDto;
import io.tackle.pathfinder.dto.ApplicationDto;
import io.tackle.pathfinder.dto.AssessmentDto;
import io.tackle.pathfinder.dto.AssessmentHeaderDto;
Expand Down Expand Up @@ -93,4 +94,12 @@ public List<LandscapeDto> getLandscape(@NotNull @Valid List<ApplicationDto> appl
return service.landscape(applicationIds.stream().map(e -> e.getApplicationId()).collect(Collectors.toList()));
}

@POST
@Path("/confidence")
@Produces("application/json")
@Consumes("application/json")
public List<AdoptionCandidateDto> adoptionCandidate(@NotNull @Valid List<ApplicationDto> applicationId) {
return service.getAdoptionCandidate(applicationId.stream().map(a -> a.getApplicationId()).collect(Collectors.toList()));
}

}
20 changes: 20 additions & 0 deletions src/main/java/io/tackle/pathfinder/dto/AdoptionCandidateDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.tackle.pathfinder.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection
public class AdoptionCandidateDto {
public Long applicationId;
public Long assessmentId;
public Integer confidence;
}
71 changes: 71 additions & 0 deletions src/main/java/io/tackle/pathfinder/services/AssessmentSvc.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.tackle.pathfinder.services;

import com.google.common.util.concurrent.AtomicDouble;
import io.tackle.pathfinder.dto.*;
import io.tackle.pathfinder.mapper.AssessmentMapper;
import io.tackle.pathfinder.model.Risk;
Expand All @@ -16,6 +17,7 @@
import io.tackle.pathfinder.model.questionnaire.SingleOption;
import lombok.Value;
import lombok.extern.java.Log;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.apache.commons.lang3.StringUtils;

import javax.enterprise.context.ApplicationScoped;
Expand All @@ -31,8 +33,11 @@

import java.util.*;
import java.util.function.Function;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

Expand All @@ -45,6 +50,29 @@ public class AssessmentSvc {
@Inject
EntityManager entityManager;

@ConfigProperty(name = "confidence.risk.RED.weight")
Integer redWeight;
@ConfigProperty(name = "confidence.risk.GREEN.weight")
Integer greenWeight;
@ConfigProperty(name = "confidence.risk.AMBER.weight")
Integer amberWeight;
@ConfigProperty(name = "confidence.risk.UNKNOWN.weight")
Integer unknownWeight;

@ConfigProperty(name = "confidence.risk.AMBER.multiplier")
Double amberMultiplier;
@ConfigProperty(name = "confidence.risk.RED.multiplier")
Double redMultiplier;

@ConfigProperty(name = "confidence.risk.RED.adjuster")
Double redAdjuster;
@ConfigProperty(name = "confidence.risk.AMBER.adjuster")
Double amberAdjuster;
@ConfigProperty(name = "confidence.risk.GREEN.adjuster")
Double greenAdjuster;
@ConfigProperty(name = "confidence.risk.UNKNOWN.adjuster")
Double unknownAdjuster;

public Optional<AssessmentHeaderDto> getAssessmentHeaderDtoByApplicationId(@NotNull Long applicationId) {
List<Assessment> assessmentQuery = Assessment.list("application_id", applicationId);
return assessmentQuery.stream().findFirst().map(e -> mapper.assessmentToAssessmentHeaderDto(e));
Expand Down Expand Up @@ -357,6 +385,49 @@ public List<RiskLineDto> identifiedRisks(List<Long> applicationList) {
Query query = entityManager.createNativeQuery(sqlString);
return mapper.riskListQueryToRiskLineDtoList(query.getResultList());
}
@Transactional
public List<AdoptionCandidateDto> getAdoptionCandidate(List<Long> applicationId) {
return applicationId.stream()
.map(a-> Assessment.find("applicationId", a).firstResultOptional())
.filter(b -> b.isPresent())
.map(c -> new AdoptionCandidateDto(((Assessment) c.get()).applicationId, ((Assessment) c.get()).id, calculateConfidence((Assessment) c.get())))
.collect(Collectors.toList());
}

private Integer calculateConfidence(Assessment assessment) {
Map<Risk, Integer> weightMap = Map.of(Risk.RED, redWeight,
Risk.UNKNOWN, unknownWeight,
Risk.AMBER, amberWeight,
Risk.GREEN, greenWeight);

List<AssessmentSingleOption> answeredOptions = assessment.assessmentQuestionnaire.categories.stream()
.flatMap(cat -> cat.questions.stream())
.flatMap(que -> que.singleOptions.stream())
.filter(opt -> opt.selected)
.collect(Collectors.toList());
long totalAnswered = answeredOptions.stream().count();

// Grouping to know how many answers per Risk
Map<Risk, Long> answersCountByRisk = answeredOptions.stream()
.collect(Collectors.groupingBy(a -> a.risk, Collectors.counting()));


BigDecimal result = getConfidenceTacklePathfinder(weightMap, answeredOptions, totalAnswered, answersCountByRisk);

return result.intValue();
}

private BigDecimal getConfidenceTacklePathfinder(Map<Risk, Integer> weightMap, List<AssessmentSingleOption> answeredOptions, long totalAnswered, Map<Risk, Long> answersCountByRisk) {
Map<Risk, Double> adjusterBase = Map.of(Risk.RED, redAdjuster, Risk.AMBER, amberAdjuster, Risk.GREEN, greenAdjuster, Risk.UNKNOWN, unknownAdjuster);

double answeredWeight = answeredOptions.stream().mapToDouble(a -> weightMap.get(a.risk) * adjusterBase.getOrDefault(a.risk, 1d)).sum();

long maxWeight = weightMap.get(Risk.GREEN) * totalAnswered;

BigDecimal result = new BigDecimal(answeredWeight / maxWeight * 100);
result.setScale(0, RoundingMode.DOWN);
return result;
}

private AssessmentRiskDto sqlRowToAssessmentRisk(Object row) {
return new AssessmentRiskDto((Integer) ((Object[]) row)[0], (String) ((Object[]) row)[1], (Integer) ((Object[]) row)[2]);
Expand Down
Loading