Skip to content

Commit 44dd357

Browse files
authored
Merge pull request #192 from q-rapids/develop
Release v2.0
2 parents b870aac + 0a6fd5d commit 44dd357

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1117
-256
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ dependencies {
8383
//API QR Generator
8484
compile files('libs/qrapids-qr_generator-0.2.jar')
8585

86+
//Add qr-eval jar compilation
87+
compile files('libs/qrapids-eval-2.0.jar')
8688

8789
testCompile('org.springframework.boot:spring-boot-starter-test')
8890
compile('org.apache.logging.log4j:log4j-api:2.9.1')

docs/asciidoc/index.html

Lines changed: 128 additions & 66 deletions
Large diffs are not rendered by default.

libs/qrapids-eval-2.0.jar

41.5 KB
Binary file not shown.

src/main/java/com/upc/gessi/qrapids/QrapidsApplication.java

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,81 @@
11
package com.upc.gessi.qrapids;
22

3-
import com.upc.gessi.qrapids.app.domain.controllers.MetricsController;
4-
import com.upc.gessi.qrapids.app.domain.controllers.FactorsController;
5-
import com.upc.gessi.qrapids.app.domain.controllers.StrategicIndicatorsController;
3+
import com.upc.gessi.qrapids.app.domain.controllers.*;
4+
import com.upc.gessi.qrapids.app.domain.exceptions.CategoriesException;
5+
import com.upc.gessi.qrapids.app.domain.exceptions.ProjectNotFoundException;
66
import com.upc.gessi.qrapids.app.domain.models.MetricCategory;
77
import com.upc.gessi.qrapids.app.domain.models.QFCategory;
88
import com.upc.gessi.qrapids.app.domain.models.SICategory;
99
import com.upc.gessi.qrapids.app.presentation.rest.services.Alerts;
1010
import org.slf4j.Logger;
1111
import org.slf4j.LoggerFactory;
12+
import org.springframework.beans.factory.annotation.Value;
1213
import org.springframework.boot.SpringApplication;
1314
import org.springframework.boot.autoconfigure.SpringBootApplication;
1415
import org.springframework.boot.builder.SpringApplicationBuilder;
1516
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
1617
import org.springframework.context.ConfigurableApplicationContext;
1718
import org.springframework.context.annotation.Bean;
19+
import org.springframework.scheduling.annotation.EnableScheduling;
20+
import org.springframework.scheduling.annotation.Scheduled;
1821
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1922

20-
import java.util.ArrayList;
21-
import java.util.HashMap;
22-
import java.util.List;
23-
import java.util.Map;
23+
import java.io.IOException;
24+
import java.text.ParseException;
25+
import java.time.ZoneId;
26+
import java.util.*;
27+
import eval2.Eval;
28+
import java.time.LocalDate;
2429

2530
@SpringBootApplication
31+
@EnableScheduling
2632
public class QrapidsApplication extends SpringBootServletInitializer {
2733

2834
@Override
2935
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
3036
return application.sources(QrapidsApplication.class);
3137
}
3238

33-
@Bean
34-
public BCryptPasswordEncoder bCryptPasswordEncoder() {
35-
return new BCryptPasswordEncoder();
36-
}
39+
@Bean
40+
public BCryptPasswordEncoder bCryptPasswordEncoder() {
41+
return new BCryptPasswordEncoder();
42+
}
43+
44+
@Value("${projects.dir:}") // default -> empty string
45+
private String projectsDir;
46+
47+
static ConfigurableApplicationContext context;
48+
49+
@Scheduled(cron = "${cron.expression:-}") // default -> disable scheduled task
50+
public void scheduleTask() throws ParseException, ProjectNotFoundException, IOException, CategoriesException {
51+
// ToDo: decide if we also copy this code to assessSI function
52+
LocalDate evaluationLocalDate = LocalDate.now(); // we need LocalDate for assessStrategicIndicators
53+
Date evaluationDate= Date.from(evaluationLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); // we need Date for evaluateQualityModel in qrapids-eval libs
54+
55+
// params config:
56+
// projects dir path, evaluationDate, null
57+
// projects dir path, fromDate, toDate
58+
Eval.evaluateQualityModel(projectsDir, evaluationDate, null);
59+
60+
boolean correct = true;
61+
// first assess factors for all projects
62+
correct = context.getBean(FactorsController.class).assessQualityFactors(null, evaluationLocalDate);
63+
64+
if (correct) {
65+
// then assess strategic indicator for all projects
66+
correct = context.getBean(StrategicIndicatorsController.class).assessStrategicIndicators(null, evaluationLocalDate);
67+
}
68+
69+
if (!correct) { // check if the assessment complete with error
70+
Logger logger = LoggerFactory.getLogger(Alerts.class);
71+
logger.error(evaluationLocalDate + ": factors or strategic indicators assessment complete with error.");
72+
}
73+
}
74+
3775

3876
public static void main(String[] args) throws Exception {
3977

40-
ConfigurableApplicationContext context = SpringApplication.run(QrapidsApplication.class, args);
78+
context = SpringApplication.run(QrapidsApplication.class, args);
4179

4280
// Check the categories in the SQL database and if they are empty create the default ones
4381
List<SICategory> siCategoryList = context.getBean(StrategicIndicatorsController.class).getStrategicIndicatorCategories();

src/main/java/com/upc/gessi/qrapids/app/domain/adapters/AssesSI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class AssesSI {
2929
@Autowired
3030
private StrategicIndicatorsController strategicIndicatorsController;
3131

32-
@Value("${assessSI.url}")
32+
@Value("${assessSI.url:}")
3333
private String url;
3434

3535
public List<DTOAssessment> assesSI(String siId, Map<String, String> mapFactors, File network) {

src/main/java/com/upc/gessi/qrapids/app/domain/controllers/AlertsController.java

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.upc.gessi.qrapids.app.domain.controllers;
22

3-
import com.upc.gessi.qrapids.app.domain.models.Alert;
4-
import com.upc.gessi.qrapids.app.domain.models.AlertStatus;
5-
import com.upc.gessi.qrapids.app.domain.models.AlertType;
6-
import com.upc.gessi.qrapids.app.domain.models.Project;
3+
import com.upc.gessi.qrapids.app.domain.exceptions.ProjectNotFoundException;
4+
import com.upc.gessi.qrapids.app.domain.models.*;
75
import com.upc.gessi.qrapids.app.domain.repositories.Alert.AlertRepository;
86
import com.upc.gessi.qrapids.app.domain.exceptions.AlertNotFoundException;
7+
import com.upc.gessi.qrapids.app.domain.repositories.Metric.MetricRepository;
8+
import com.upc.gessi.qrapids.app.domain.repositories.Profile.ProfileProjectStrategicIndicatorsRepository;
9+
import com.upc.gessi.qrapids.app.domain.repositories.Project.ProjectRepository;
10+
import com.upc.gessi.qrapids.app.domain.repositories.QualityFactor.QualityFactorRepository;
11+
import com.upc.gessi.qrapids.app.domain.repositories.StrategicIndicator.StrategicIndicatorRepository;
912
import org.springframework.beans.factory.annotation.Autowired;
1013
import org.springframework.data.util.Pair;
1114
import org.springframework.stereotype.Service;
@@ -21,9 +24,30 @@ public class AlertsController {
2124
@Autowired
2225
private AlertRepository alertRepository;
2326

27+
@Autowired
28+
private ProjectRepository projectRepository;
29+
30+
@Autowired
31+
private MetricRepository metricRepository;
32+
33+
@Autowired
34+
private QualityFactorRepository factorRepository;
35+
36+
@Autowired
37+
private StrategicIndicatorRepository strategicIndicatorRepository;
38+
39+
@Autowired
40+
private ProfileProjectStrategicIndicatorsRepository profileProjectStrategicIndicatorsRepository;
41+
2442
@Autowired
2543
private QRPatternsController qrPatternsController;
2644

45+
@Autowired
46+
private ProjectsController projectsController;
47+
48+
@Autowired
49+
private ProfilesController profilesController;
50+
2751
public Alert getAlertById(long alertId) throws AlertNotFoundException {
2852
Optional<Alert> alertOptional = alertRepository.findById(alertId);
2953
if (alertOptional.isPresent()) {
@@ -52,10 +76,109 @@ public Pair<Long, Long> countNewAlerts(Project project) {
5276
return Pair.of(newAlerts, newAlertsWithQR);
5377
}
5478

79+
public Pair<Long, Long> countNewAlertsByProfile(Project project, String profileId) throws ProjectNotFoundException {
80+
long newAlertsCount = alertRepository.countByProject_IdAndStatus(project.getId(), AlertStatus.NEW);
81+
long newAlertsWithQRCount = alertRepository.countByProject_IdAndReqAssociatIsTrueAndStatusEquals(project.getId(), AlertStatus.NEW);
82+
if ((profileId != null) && (!profileId.equals("null"))) { // if profile not null
83+
Profile profile = profilesController.findProfileById(profileId);
84+
if (profile.getAllSIByProject(project)) { // if allSI true --> return all new alerts count
85+
return Pair.of(newAlertsCount, newAlertsWithQRCount);
86+
} else { // if allSI false --> return filtered new alerts
87+
List<Alert> allNewAlerts = alertRepository.getByProject_IdAndStatus(project.getId(), AlertStatus.NEW);
88+
List<Alert> allNewAlertsWithQR = alertRepository.getByProject_IdAndReqAssociatIsTrueAndStatusEquals(project.getId(), AlertStatus.NEW);
89+
List<Alert> filteredNewAlerts = filterByProfile(project, profile, allNewAlerts);
90+
List<Alert> filteredNewAlertsWithQR = filterByProfile(project, profile, allNewAlertsWithQR);
91+
return Pair.of(Long.valueOf(filteredNewAlerts.size()), Long.valueOf(filteredNewAlertsWithQR.size()));
92+
}
93+
} else { // if profile is null --> return all alerts
94+
return Pair.of(newAlertsCount, newAlertsWithQRCount);
95+
}
96+
}
97+
5598
public void createAlert (String id, String name, AlertType type, float value, float threshold, String category, Project project) {
5699
Alert alert = new Alert(id, name, type, value, threshold, category, new Date(), AlertStatus.NEW, false, project);
57100
boolean hasReq = qrPatternsController.existsPatternForAlert(alert);
58101
alert.setReqAssociat(hasReq);
59102
alertRepository.save(alert);
60103
}
104+
105+
public void checkMetricAlert(String externalId, float value, String prj){
106+
// get project from data base
107+
Project p = projectRepository.findByExternalId(prj);
108+
// get metric threshold from data base
109+
Metric m = metricRepository.findByExternalIdAndProjectId(externalId, p.getId());
110+
// check if the value is below the threshold then create new alert for this metric
111+
if (m.getThreshold() != null && value < m.getThreshold()) {
112+
// createAlert( id, name, type, value, threshold, category, project)
113+
createAlert(externalId, m.getName(), AlertType.METRIC, value, m.getThreshold(), externalId, p);
114+
}
115+
}
116+
117+
public void checkFactorAlert(String externalId, float value, String prj){
118+
// get project from data base
119+
Project p = projectRepository.findByExternalId(prj);
120+
// get factor threshold from data base
121+
Factor f = factorRepository.findByExternalIdAndProjectId(externalId, p.getId());
122+
// check if the value is below the threshold then create new alert for this factor
123+
if (f.getThreshold() != null && value < f.getThreshold()) {
124+
// createAlert( id, name, type, value, threshold, category, project)
125+
createAlert(externalId, f.getName(), AlertType.FACTOR, value, f.getThreshold(), externalId, p);
126+
}
127+
}
128+
129+
public void checkStrategicIndicatorAlert(String externalId, float value, String prj){
130+
// get project from data base
131+
Project p = projectRepository.findByExternalId(prj);
132+
// get factor threshold from data base
133+
Strategic_Indicator si = strategicIndicatorRepository.findByExternalIdAndProjectId(externalId, p.getId());
134+
// check if the value is below the threshold then create new alert for this factor
135+
if (si.getThreshold() != null && value < si.getThreshold()) {
136+
// createAlert( id, name, type, value, threshold, category, project)
137+
createAlert(externalId, si.getName(), AlertType.STRATEGIC_INDICATOR, value, si.getThreshold(), externalId, p);
138+
}
139+
}
140+
141+
public List<Alert> getAlertsByProjectAndProfile(Project project, String profileId) throws ProjectNotFoundException {
142+
List<Alert> alerts = alertRepository.findByProject_IdOrderByDateDesc(project.getId());
143+
if ((profileId != null) && (!profileId.equals("null"))) { // if profile not null
144+
Profile profile = profilesController.findProfileById(profileId);
145+
if (profile.getAllSIByProject(project)) { // allSI true --> filter only by profile quality level
146+
if(profile.getQualityLevel().equals(Profile.QualityLevel.METRICS_FACTORS))
147+
alerts.removeIf(a -> a.getType().equals(AlertType.STRATEGIC_INDICATOR));
148+
else if (profile.getQualityLevel().equals(Profile.QualityLevel.METRICS)) {
149+
alerts.removeIf(a -> a.getType().equals(AlertType.STRATEGIC_INDICATOR));
150+
alerts.removeIf(a -> a.getType().equals(AlertType.FACTOR));
151+
}
152+
return alerts;
153+
} else { // if allSI false --> return alerts filtered by profile quality level and SIs
154+
return filterByProfile(project,profile,alerts);
155+
}
156+
} else { // if profile is null --> return all alerts
157+
return alerts;
158+
}
159+
}
160+
161+
public List <Alert> filterByProfile (Project project, Profile profile, List<Alert> alerts) {
162+
List<ProfileProjectStrategicIndicators> ppsiList =
163+
profileProjectStrategicIndicatorsRepository.findByProfileAndProject(profile,project);
164+
List<Alert> result = new ArrayList<>();
165+
Profile.QualityLevel ql = profile.getQualityLevel();
166+
for (Alert a : alerts) {
167+
for (ProfileProjectStrategicIndicators ppsi : ppsiList) {
168+
if (a.getType().equals(AlertType.STRATEGIC_INDICATOR) && a.getId_element().equals(ppsi.getStrategicIndicator().getExternalId()) && !result.contains(a)
169+
&& ql.equals(Profile.QualityLevel.ALL)) result.add(a);
170+
List<StrategicIndicatorQualityFactors> siqfList = ppsi.getStrategicIndicator().getStrategicIndicatorQualityFactorsList();
171+
for (StrategicIndicatorQualityFactors siqf : siqfList) {
172+
if (a.getType().equals(AlertType.FACTOR) && a.getId_element().equals(siqf.getFactor().getExternalId()) && !result.contains(a)
173+
&& (ql.equals(Profile.QualityLevel.ALL) || ql.equals(Profile.QualityLevel.METRICS_FACTORS))) result.add(a);
174+
List<String> metrics = siqf.getFactor().getMetrics();
175+
for (String m : metrics) {
176+
if (a.getType().equals(AlertType.METRIC) && a.getId_element().equals(m) && !result.contains(a))
177+
result.add(a);
178+
}
179+
}
180+
}
181+
}
182+
return result;
183+
}
61184
}

src/main/java/com/upc/gessi/qrapids/app/domain/controllers/FactorsController.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public class FactorsController {
4848
@Autowired
4949
private ProfileProjectStrategicIndicatorsRepository profileProjectStrategicIndicatorsRepository;
5050

51+
@Autowired
52+
private AlertsController alertsController;
53+
5154
@Autowired
5255
private MetricsController metricsController;
5356

@@ -182,10 +185,14 @@ public Factor getQualityFactorById (Long qualityFactorId) throws QualityFactorNo
182185
}
183186
}
184187

185-
public Factor saveQualityFactor(String name, String description, List<String> qualityMetrics, Project project) throws MetricNotFoundException {
188+
public Factor saveQualityFactor(String name, String description, String threshold, List<String> qualityMetrics, Project project) throws MetricNotFoundException {
186189
Factor qualityFactor;
187190
// create Quality Factor minim (without quality factors and weighted)
188191
qualityFactor = new Factor (name, description, project);
192+
if (!threshold.isEmpty()) // check if threshold is specified and then set it
193+
qualityFactor.setThreshold(Float.parseFloat(threshold));
194+
else
195+
qualityFactor.setThreshold(null);
189196
qualityFactorRepository.save(qualityFactor);
190197
boolean weighted = assignQualityMetricsToQualityFactor (qualityMetrics, qualityFactor);
191198
qualityFactor.setWeighted(weighted);
@@ -220,10 +227,14 @@ private boolean assignQualityMetricsToQualityFactor (List<String> qualityMetrics
220227
return weighted;
221228
}
222229

223-
public Factor editQualityFactor (Long factorId, String name, String description, List<String> qualityMetrics) throws QualityFactorNotFoundException, QualityFactorMetricsNotFoundException, MetricNotFoundException {
230+
public Factor editQualityFactor(Long factorId, String name, String description, String threshold, List<String> qualityMetrics) throws QualityFactorNotFoundException, QualityFactorMetricsNotFoundException, MetricNotFoundException {
224231
Factor factor = getQualityFactorById(factorId);
225232
factor.setName(name);
226233
factor.setDescription(description);
234+
if (!threshold.isEmpty()) // check if threshold is specified and then set it
235+
factor.setThreshold(Float.parseFloat(threshold));
236+
else
237+
factor.setThreshold(null);
227238
// Actualize Quality Metrics
228239
boolean weighted = reassignQualityMetricsToQualityFactor (qualityMetrics, factor);
229240
factor.setWeighted(weighted);
@@ -326,6 +337,11 @@ private boolean assessDateProjectQualityFactors(String project, LocalDate evalua
326337
metricList = metricsController.getAllMetricsHistoricalEvaluation(project, null, evaluationDate, evaluationDate);
327338
metricEvaluationQma.setMetrics(metricList);
328339

340+
// CHECK METRICS ALERTS
341+
for (DTOMetricEvaluation m : metricList) {
342+
alertsController.checkMetricAlert(m.getId(), m.getValue(), project);
343+
}
344+
329345
return assessProjectQualityFactors(evaluationDate, project, metricEvaluationQma);
330346
}
331347

@@ -507,6 +523,8 @@ private String assessQualityFactors(LocalDate evaluationDate, String project, Fa
507523
indicators
508524
))
509525
throw new AssessmentErrorException();
526+
// CHECK FACTORS ALERTS
527+
alertsController.checkFactorAlert(qualityFactor.getExternalId(),value,project);
510528
}
511529
return assessmentValueOrLabel;
512530
}
@@ -526,7 +544,6 @@ public boolean assessQualityFactor(String name, String prj) throws IOException,
526544
MetricEvaluation metricEvaluationQma = new MetricEvaluation();
527545

528546
// We will compute the evaluation values for the QF for THIS CONCRETE component
529-
530547
// 1.- We need to remove old data from metric evaluations in the quality_factors relationship attribute
531548
metricEvaluationQma.setMetrics(metricsController.getAllMetricsEvaluation(prj, null));
532549
metricEvaluationQma.clearQualityFactorsRelations(qf.getExternalId());
@@ -583,16 +600,6 @@ public void setFactorStrategicIndicatorRelation (List<DTOFactorEvaluation> facto
583600
qmaQualityFactors.setFactorStrategicIndicatorRelation(factorList, projectExternalId);
584601
}
585602

586-
/*public static String getFactorLabelFromValue(Float f) {
587-
List <QFCategory> qfCategoryList = factorCategoryRepository.findAllByOrderByUpperThresholdAsc();
588-
if (f != null) {
589-
for (QFCategory qfCategory : qfCategoryList) {
590-
if (f <= qfCategory.getUpperThreshold())
591-
return qfCategory.getName();
592-
}
593-
}
594-
return "No Category";
595-
}*/
596603
public String getFactorLabelFromValue (Float f) {
597604
List <QFCategory> qfCategoryList = factorCategoryRepository.findAllByOrderByUpperThresholdAsc();
598605
if (f != null) {

0 commit comments

Comments
 (0)