Skip to content

Commit 2806b55

Browse files
Merge pull request #989 from exadel-inc/EFRS-1348_remove_quartz
EFRS-1348: Removed Quartz
2 parents 08c63de + 05a0b67 commit 2806b55

File tree

13 files changed

+584
-183
lines changed

13 files changed

+584
-183
lines changed

java/admin/pom.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,6 @@
5151
<groupId>org.springframework.cloud</groupId>
5252
<artifactId>spring-cloud-starter-openfeign</artifactId>
5353
</dependency>
54-
<dependency>
55-
<groupId>org.springframework.boot</groupId>
56-
<artifactId>spring-boot-starter-quartz</artifactId>
57-
</dependency>
5854
<dependency>
5955
<groupId>org.projectlombok</groupId>
6056
<artifactId>lombok</artifactId>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.exadel.frs.service;
2+
3+
import static com.exadel.frs.commonservice.enums.GlobalRole.OWNER;
4+
import static org.apache.commons.lang3.Range.between;
5+
import static org.apache.commons.lang3.StringUtils.isNotBlank;
6+
import com.exadel.frs.commonservice.entity.InstallInfo;
7+
import com.exadel.frs.commonservice.projection.ModelSubjectProjection;
8+
import com.exadel.frs.commonservice.entity.User;
9+
import com.exadel.frs.commonservice.exception.ApperyServiceException;
10+
import com.exadel.frs.commonservice.repository.InstallInfoRepository;
11+
import com.exadel.frs.commonservice.repository.ModelRepository;
12+
import com.exadel.frs.commonservice.repository.UserRepository;
13+
import com.exadel.frs.commonservice.system.feign.ApperyStatisticsClient;
14+
import com.exadel.frs.commonservice.system.feign.StatisticsFacesEntity;
15+
import feign.FeignException;
16+
import java.util.List;
17+
import lombok.RequiredArgsConstructor;
18+
import lombok.extern.slf4j.Slf4j;
19+
import org.apache.commons.lang3.Range;
20+
import org.springframework.beans.factory.annotation.Value;
21+
import org.springframework.scheduling.annotation.Scheduled;
22+
import org.springframework.stereotype.Service;
23+
24+
@Slf4j
25+
@Service
26+
@RequiredArgsConstructor
27+
public class StatisticService {
28+
29+
private static final List<Range<Long>> RANGES = List.of(
30+
between(1L, 10L), between(11L, 50L), between(51L, 200L),
31+
between(201L, 500L), between(501L, 2000L), between(2001L, 10000L),
32+
between(10001L, 50000L), between(50001L, 200000L), between(200001L, 1000000L)
33+
);
34+
35+
@Value("${app.feign.appery-io.api-key}")
36+
private String apperyApiKey;
37+
38+
private final ApperyStatisticsClient apperyClient;
39+
private final InstallInfoRepository installInfoRepository;
40+
private final ModelRepository modelRepository;
41+
private final UserRepository userRepository;
42+
43+
@Scheduled(cron = "@midnight", zone = "UTC")
44+
public void recordStatistics() {
45+
boolean statisticsAreNotAllowed = !areStatisticsAllowed();
46+
if (statisticsAreNotAllowed) {
47+
log.info("Statistics are not allowed");
48+
return;
49+
}
50+
51+
List<ModelSubjectProjection> subjectCountPerModel = modelRepository.getModelSubjectsCount();
52+
InstallInfo installInfo = installInfoRepository.findTopByOrderByInstallGuid();
53+
54+
if (installInfo == null) {
55+
log.warn("In order to record statistics, at least one InstallInfo must be present");
56+
return;
57+
}
58+
59+
List<StatisticsFacesEntity> statistics = createStatistics(installInfo.getInstallGuid(), subjectCountPerModel);
60+
sendStatistics(statistics);
61+
}
62+
63+
private boolean areStatisticsAllowed() {
64+
if (isNotBlank(apperyApiKey)) {
65+
User owner = userRepository.findByGlobalRole(OWNER);
66+
return owner != null && owner.isAllowStatistics();
67+
} else {
68+
return false;
69+
}
70+
}
71+
72+
private List<StatisticsFacesEntity> createStatistics(String installInfoGuid, List<ModelSubjectProjection> subjectCountPerModel) {
73+
return subjectCountPerModel.stream()
74+
.map(subjectCount -> createStatistic(installInfoGuid, subjectCount))
75+
.toList();
76+
}
77+
78+
private StatisticsFacesEntity createStatistic(String installInfoGuid, ModelSubjectProjection subjectCount) {
79+
return new StatisticsFacesEntity(
80+
installInfoGuid,
81+
subjectCount.guid(),
82+
getSubjectRange(subjectCount.subjectCount())
83+
);
84+
}
85+
86+
private String getSubjectRange(Long subjectCount) {
87+
if (subjectCount == null || subjectCount == 0) {
88+
return "0";
89+
}
90+
91+
return RANGES.stream()
92+
.filter(range -> range.contains(subjectCount))
93+
.map(range -> range.getMinimum() + "-" + range.getMaximum())
94+
.findFirst()
95+
.orElse("1000001+");
96+
}
97+
98+
private void sendStatistics(List<StatisticsFacesEntity> statistics) {
99+
try {
100+
statistics
101+
.forEach(statistic -> apperyClient.create(apperyApiKey, statistic));
102+
} catch (FeignException e) {
103+
log.error(e.getMessage(), e);
104+
throw new ApperyServiceException();
105+
}
106+
}
107+
}

java/admin/src/main/resources/application.yml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,6 @@ spring:
8282
auth: true
8383
main:
8484
allow-bean-definition-overriding: true
85-
quartz:
86-
job-store-type: jdbc
87-
jdbc:
88-
initialize-schema: always
89-
properties:
90-
org.quartz:
91-
scheduler:
92-
instanceName: statistics scheduler
93-
instanceId: AUTO
94-
jobStore:
95-
driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
96-
threadPool:
97-
# thread pool capacity (default is 10)
98-
threadCount: 1
9985

10086
security:
10187
signing-key: MaYzkSjmkzPC57L
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
databaseChangeLog:
2+
- changeSet:
3+
id: drop-qrtz_blob_triggers_table
4+
author: Volodymyr Bushko
5+
preConditions:
6+
- onFail: MARK_RAN
7+
- tableExists:
8+
schemaName: public
9+
tableName: qrtz_blob_triggers
10+
changes:
11+
- dropTable:
12+
cascadeConstraints: true
13+
schemaName: public
14+
tableName: qrtz_blob_triggers
15+
- changeSet:
16+
id: drop-qrtz_calendars-table
17+
author: Volodymyr Bushko
18+
preConditions:
19+
- onFail: MARK_RAN
20+
- tableExists:
21+
schemaName: public
22+
tableName: qrtz_calendars
23+
changes:
24+
- dropTable:
25+
cascadeConstraints: true
26+
schemaName: public
27+
tableName: qrtz_calendars
28+
- changeSet:
29+
id: drop-qrtz_cron_triggers-table
30+
author: Volodymyr Bushko
31+
preConditions:
32+
- onFail: MARK_RAN
33+
- tableExists:
34+
schemaName: public
35+
tableName: qrtz_cron_triggers
36+
changes:
37+
- dropTable:
38+
cascadeConstraints: true
39+
schemaName: public
40+
tableName: qrtz_cron_triggers
41+
- changeSet:
42+
id: drop-qrtz_fired_triggers-table
43+
author: Volodymyr Bushko
44+
preConditions:
45+
- onFail: MARK_RAN
46+
- tableExists:
47+
schemaName: public
48+
tableName: qrtz_fired_triggers
49+
changes:
50+
- dropTable:
51+
cascadeConstraints: true
52+
schemaName: public
53+
tableName: qrtz_fired_triggers
54+
- changeSet:
55+
id: drop-qrtz_job_details-table
56+
author: Volodymyr Bushko
57+
preConditions:
58+
- onFail: MARK_RAN
59+
- tableExists:
60+
schemaName: public
61+
tableName: qrtz_job_details
62+
changes:
63+
- dropTable:
64+
cascadeConstraints: true
65+
schemaName: public
66+
tableName: qrtz_job_details
67+
- changeSet:
68+
id: drop-qrtz_locks-table
69+
author: Volodymyr Bushko
70+
preConditions:
71+
- onFail: MARK_RAN
72+
- tableExists:
73+
schemaName: public
74+
tableName: qrtz_locks
75+
changes:
76+
- dropTable:
77+
cascadeConstraints: true
78+
schemaName: public
79+
tableName: qrtz_locks
80+
- changeSet:
81+
id: drop-qrtz_paused_trigger_grps-table
82+
author: Volodymyr Bushko
83+
preConditions:
84+
- onFail: MARK_RAN
85+
- tableExists:
86+
schemaName: public
87+
tableName: qrtz_paused_trigger_grps
88+
changes:
89+
- dropTable:
90+
cascadeConstraints: true
91+
schemaName: public
92+
tableName: qrtz_paused_trigger_grps
93+
- changeSet:
94+
id: drop-qrtz_scheduler_state-table
95+
author: Volodymyr Bushko
96+
preConditions:
97+
- onFail: MARK_RAN
98+
- tableExists:
99+
schemaName: public
100+
tableName: qrtz_scheduler_state
101+
changes:
102+
- dropTable:
103+
cascadeConstraints: true
104+
schemaName: public
105+
tableName: qrtz_scheduler_state
106+
- changeSet:
107+
id: drop-qrtz_simple_triggers-table
108+
author: Volodymyr Bushko
109+
preConditions:
110+
- onFail: MARK_RAN
111+
- tableExists:
112+
schemaName: public
113+
tableName: qrtz_simple_triggers
114+
changes:
115+
- dropTable:
116+
cascadeConstraints: true
117+
schemaName: public
118+
tableName: qrtz_simple_triggers
119+
- changeSet:
120+
id: drop-qrtz_simprop_triggers-table
121+
author: Volodymyr Bushko
122+
preConditions:
123+
- onFail: MARK_RAN
124+
- tableExists:
125+
schemaName: public
126+
tableName: qrtz_simprop_triggers
127+
changes:
128+
- dropTable:
129+
cascadeConstraints: true
130+
schemaName: public
131+
tableName: qrtz_simprop_triggers
132+
- changeSet:
133+
id: drop-qrtz_triggers-table
134+
author: Volodymyr Bushko
135+
preConditions:
136+
- onFail: MARK_RAN
137+
- tableExists:
138+
schemaName: public
139+
tableName: qrtz_triggers
140+
changes:
141+
- dropTable:
142+
cascadeConstraints: true
143+
schemaName: public
144+
tableName: qrtz_triggers

java/admin/src/main/resources/db/changelog/db.changelog-master.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ databaseChangeLog:
5151
file: db/changelog/db.changelog-0.2.5.yaml
5252
- include:
5353
file: db/changelog/db.changelog-0.2.6.yaml
54+
- include:
55+
file: db/changelog/db.changelog-0.2.7.yaml

java/admin/src/test/java/com/exadel/frs/DbHelper.java

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
package com.exadel.frs;
22

3+
import static com.exadel.frs.ItemsBuilder.makeApp;
4+
import static com.exadel.frs.ItemsBuilder.makeEmbedding;
5+
import static com.exadel.frs.ItemsBuilder.makeImg;
6+
import static com.exadel.frs.ItemsBuilder.makeModel;
7+
import static com.exadel.frs.ItemsBuilder.makeSubject;
8+
import static com.exadel.frs.commonservice.enums.GlobalRole.USER;
9+
import static java.time.LocalDateTime.now;
10+
import static java.time.ZoneOffset.UTC;
11+
import static java.time.temporal.ChronoUnit.MILLIS;
12+
import static java.util.UUID.randomUUID;
313
import com.exadel.frs.commonservice.entity.Embedding;
414
import com.exadel.frs.commonservice.entity.Img;
515
import com.exadel.frs.commonservice.entity.Model;
616
import com.exadel.frs.commonservice.entity.ModelStatistic;
717
import com.exadel.frs.commonservice.entity.ResetPasswordToken;
818
import com.exadel.frs.commonservice.entity.Subject;
919
import com.exadel.frs.commonservice.entity.User;
20+
import com.exadel.frs.commonservice.enums.GlobalRole;
1021
import com.exadel.frs.commonservice.enums.ModelType;
1122
import com.exadel.frs.commonservice.repository.EmbeddingRepository;
1223
import com.exadel.frs.commonservice.repository.ImgRepository;
@@ -15,23 +26,14 @@
1526
import com.exadel.frs.commonservice.repository.SubjectRepository;
1627
import com.exadel.frs.commonservice.repository.UserRepository;
1728
import com.exadel.frs.repository.AppRepository;
18-
import java.time.LocalDateTime;
1929
import com.exadel.frs.repository.ResetPasswordTokenRepository;
30+
import java.time.LocalDateTime;
31+
import java.util.UUID;
2032
import org.springframework.beans.factory.annotation.Autowired;
2133
import org.springframework.beans.factory.annotation.Value;
2234
import org.springframework.security.crypto.password.PasswordEncoder;
2335
import org.springframework.stereotype.Service;
2436

25-
import java.util.UUID;
26-
27-
import static com.exadel.frs.ItemsBuilder.*;
28-
import static com.exadel.frs.commonservice.enums.GlobalRole.USER;
29-
import static java.time.LocalDateTime.now;
30-
import static java.time.ZoneOffset.UTC;
31-
import static java.time.temporal.ChronoUnit.MILLIS;
32-
import static java.util.UUID.randomUUID;
33-
import static java.time.LocalDateTime.now;
34-
3537
@Service
3638
// TODO think about common helper for admin/core
3739
public class DbHelper {
@@ -143,18 +145,26 @@ public Img insertImg() {
143145
}
144146

145147
public User insertUser(String email) {
146-
var user = createUser(email);
148+
return insertUser(email, USER);
149+
}
150+
151+
public User insertUser(String email, GlobalRole role) {
152+
var user = createUser(email, role);
147153
user.setEnabled(true);
148154
return userRepository.saveAndFlush(user);
149155
}
150156

151157
public User insertUnconfirmedUser(String email) {
152-
var user = createUser(email);
158+
return insertUnconfirmedUser(email, USER);
159+
}
160+
161+
public User insertUnconfirmedUser(String email, GlobalRole role) {
162+
var user = createUser(email, role);
153163
user.setRegistrationToken(UUID.randomUUID().toString());
154164
return userRepository.saveAndFlush(user);
155165
}
156166

157-
private User createUser(String email) {
167+
private User createUser(String email, GlobalRole role) {
158168
return User.builder()
159169
.email(email)
160170
.firstName("firstName")
@@ -164,8 +174,8 @@ private User createUser(String email) {
164174
.accountNonExpired(true)
165175
.accountNonLocked(true)
166176
.credentialsNonExpired(true)
167-
.allowStatistics(false)
168-
.globalRole(USER)
177+
.allowStatistics(true)
178+
.globalRole(role)
169179
.build();
170180
}
171181

0 commit comments

Comments
 (0)