Skip to content

Commit 32ac0f0

Browse files
committed
refactor: replace tracker db request with api calls
Signed-off-by: Oleh Astappiev <4512729+astappiev@users.noreply.github.com>
1 parent 21bba5b commit 32ac0f0

File tree

7 files changed

+139
-112
lines changed

7 files changed

+139
-112
lines changed

src/main/java/de/l3s/learnweb/app/DaoProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ public class DaoProvider {
7575
private final DataSource dataSource;
7676
private final Jdbi jdbi;
7777

78-
// private SpeechRepositoryDao speechRepositoryDao;
79-
// private TrackerDao trackerDao;
8078
private final AnnouncementDao announcementDao;
8179
private final ArchiveUrlDao archiveUrlDao;
8280
private final BanDao banDao;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package de.l3s.learnweb.app;
2+
3+
import java.io.Serial;
4+
import java.io.Serializable;
5+
6+
import jakarta.enterprise.context.ApplicationScoped;
7+
import jakarta.enterprise.inject.Produces;
8+
9+
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import com.fasterxml.jackson.databind.SerializationFeature;
11+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
12+
13+
@ApplicationScoped
14+
public class ObjectMapperProducer implements Serializable {
15+
@Serial
16+
private static final long serialVersionUID = 1151315245069640668L;
17+
18+
private final ObjectMapper objectMapper;
19+
20+
public ObjectMapperProducer() {
21+
objectMapper = new ObjectMapper();
22+
// Register JavaTimeModule to handle Java 8 date/time types
23+
objectMapper.registerModule(new JavaTimeModule());
24+
// Disable writing dates as timestamps (use ISO format instead)
25+
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
26+
}
27+
28+
@Produces
29+
public ObjectMapper getObjectMapper() {
30+
return objectMapper;
31+
}
32+
}

src/main/java/de/l3s/learnweb/dashboard/tracker/TrackerDao.java

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 88 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,129 @@
11
package de.l3s.learnweb.dashboard.tracker;
22

3+
import java.io.IOException;
34
import java.io.Serial;
45
import java.io.Serializable;
6+
import java.net.URI;
7+
import java.net.http.HttpClient;
8+
import java.net.http.HttpRequest;
9+
import java.net.http.HttpResponse;
10+
import java.time.LocalDate;
511
import java.util.List;
612
import java.util.Map;
713

14+
import jakarta.enterprise.inject.spi.DeploymentException;
815
import jakarta.faces.view.ViewScoped;
16+
import jakarta.inject.Inject;
917
import jakarta.inject.Named;
1018

19+
import org.apache.commons.lang3.StringUtils;
20+
import org.apache.logging.log4j.LogManager;
21+
import org.apache.logging.log4j.Logger;
22+
23+
import com.fasterxml.jackson.core.type.TypeReference;
24+
import com.fasterxml.jackson.databind.ObjectMapper;
25+
26+
import de.l3s.learnweb.app.ConfigProvider;
1127
import de.l3s.learnweb.dashboard.CommonDashboardUserBean;
1228

1329
@Named
1430
@ViewScoped
1531
public class TrackerDashboardBean extends CommonDashboardUserBean implements Serializable {
32+
private static final Logger log = LogManager.getLogger(TrackerDashboardBean.class);
33+
1634
@Serial
1735
private static final long serialVersionUID = 3640317272542005280L;
1836

19-
private static final int TRACKER_CLIENT_ID = 2;
20-
21-
private TrackerDao trackerDao;
22-
2337
private transient Map<String, Integer> proxySources;
2438
private transient List<TrackerUserActivity> statistics;
2539

40+
@Inject
41+
private ConfigProvider config;
42+
43+
@Inject
44+
private ObjectMapper objectMapper;
45+
2646
@Override
2747
public void onLoad() {
2848
super.onLoad();
2949

30-
trackerDao = dao().getJdbi().onDemand(TrackerDao.class);
31-
cleanAndUpdateStoredData();
50+
if (StringUtils.isAnyEmpty(config.getProperty("integration_tracker_url"), config.getProperty("integration_tracker_apikey"), config.getProperty("integration_tracker_secret"))) {
51+
throw new DeploymentException("Proxy is not configured. Please contact the administrator.");
52+
}
3253
}
3354

3455
@Override
3556
public void cleanAndUpdateStoredData() {
3657
statistics = null;
3758
proxySources = null;
38-
39-
fetchDataFromManager();
40-
}
41-
42-
private void fetchDataFromManager() {
43-
if (getSelectedUsersIds() != null && !getSelectedUsersIds().isEmpty()) {
44-
List<Integer> selectedUsersIds = getSelectedUsersIds();
45-
statistics = trackerDao.countTrackerStatistics(TRACKER_CLIENT_ID, selectedUsersIds, startDate, endDate);
46-
proxySources = trackerDao.countUsagePerDomain(TRACKER_CLIENT_ID, selectedUsersIds, startDate, endDate);
47-
}
4859
}
4960

5061
public List<TrackerUserActivity> getStatistics() {
62+
if (statistics == null) {
63+
try {
64+
String response = sendApiRequest("/api/v2/statistics/users", getSelectedUsersIds(), startDate, endDate);
65+
this.statistics = objectMapper.readValue(response, new TypeReference<>() {});
66+
} catch (IOException | InterruptedException e) {
67+
log.error("Error fetching proxy sources: ", e);
68+
}
69+
}
5170
return statistics;
5271
}
5372

5473
public Map<String, Integer> getProxySources() {
74+
if (proxySources == null) {
75+
try {
76+
String response = sendApiRequest("/api/v2/statistics/domains", getSelectedUsersIds(), startDate, endDate);
77+
proxySources = objectMapper.readValue(response, new TypeReference<>() {});
78+
} catch (IOException | InterruptedException e) {
79+
log.error("Error fetching proxy sources: ", e);
80+
}
81+
}
5582
return proxySources;
5683
}
84+
85+
private String sendApiRequest(String endpoint, List<Integer> userIds, LocalDate startDate, LocalDate endDate)
86+
throws IOException, InterruptedException {
87+
String queryParams = buildQueryParameters(userIds, startDate, endDate);
88+
String url = config.getProperty("integration_tracker_url") + endpoint + queryParams;
89+
90+
HttpRequest request = HttpRequest.newBuilder()
91+
.uri(URI.create(url))
92+
.header("Authorization", "Apikey " + config.getProperty("integration_tracker_apikey"))
93+
.header("X-Secret-Key", config.getProperty("integration_tracker_secret"))
94+
.GET().build();
95+
96+
HttpResponse<String> response = HttpClient.newHttpClient()
97+
.send(request, HttpResponse.BodyHandlers.ofString());
98+
99+
if (response.statusCode() >= 400) {
100+
log.error("API request failed with status code {}: {}", response.statusCode(), response.body());
101+
throw new IOException("API request failed with status code: " + response.statusCode());
102+
}
103+
104+
return response.body();
105+
}
106+
107+
private String buildQueryParameters(List<Integer> userIds, LocalDate startDate, LocalDate endDate) {
108+
StringBuilder params = new StringBuilder("?");
109+
boolean hasParams = false;
110+
111+
if (userIds != null && !userIds.isEmpty()) {
112+
params.append("user_ids=").append(String.join(",", userIds.stream().map(String::valueOf).toList()));
113+
hasParams = true;
114+
}
115+
116+
if (startDate != null) {
117+
if (hasParams) params.append("&");
118+
params.append("start_date=").append(startDate);
119+
hasParams = true;
120+
}
121+
122+
if (endDate != null) {
123+
if (hasParams) params.append("&");
124+
params.append("end_date=").append(endDate);
125+
}
126+
127+
return params.toString();
128+
}
57129
}

src/main/java/de/l3s/learnweb/dashboard/tracker/TrackerUserActivity.java

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ public class TrackerUserActivity implements Serializable {
1717
private long timeStay;
1818
private long timeActive;
1919
private int clicks;
20-
private int keyPresses;
21-
22-
private long timeActiveInMinutes;
23-
private String timeActiveFormatted;
24-
private long timeStayInMinutes;
25-
private String timeStayFormatted;
20+
private int keypresses;
2621

2722
private transient User user;
23+
private transient String timeActiveFormatted;
24+
private transient String timeStayFormatted;
2825

2926
public User getUser() {
3027
if (null == user && userId != 0) {
@@ -55,10 +52,6 @@ public long getTimeStay() {
5552

5653
public void setTimeStay(long timeStay) {
5754
this.timeStay = timeStay;
58-
59-
Duration durationStay = Duration.ofMillis(timeStay);
60-
this.timeStayInMinutes = durationStay.toMinutes();
61-
this.timeStayFormatted = StringHelper.formatDuration(durationStay);
6255
}
6356

6457
public long getTimeActive() {
@@ -67,10 +60,6 @@ public long getTimeActive() {
6760

6861
public void setTimeActive(long timeActive) {
6962
this.timeActive = timeActive;
70-
71-
Duration durationActive = Duration.ofMillis(timeActive);
72-
this.timeActiveInMinutes = durationActive.toMinutes();
73-
this.timeActiveFormatted = StringHelper.formatDuration(durationActive);
7463
}
7564

7665
public int getClicks() {
@@ -81,43 +70,25 @@ public void setClicks(int clicks) {
8170
this.clicks = clicks;
8271
}
8372

84-
public int getKeyPresses() {
85-
return keyPresses;
86-
}
87-
88-
public void setKeyPresses(int keyPresses) {
89-
this.keyPresses = keyPresses;
73+
public int getKeypresses() {
74+
return keypresses;
9075
}
9176

92-
public long getTimeActiveInMinutes() {
93-
return timeActiveInMinutes;
94-
}
95-
96-
public void setTimeActiveInMinutes(long timeActiveInMinutes) {
97-
this.timeActiveInMinutes = timeActiveInMinutes;
77+
public void setKeypresses(int keypresses) {
78+
this.keypresses = keypresses;
9879
}
9980

10081
public String getTimeActiveFormatted() {
82+
if (timeActiveFormatted == null) {
83+
timeActiveFormatted = StringHelper.formatDuration(Duration.ofMillis(timeActive));
84+
}
10185
return timeActiveFormatted;
10286
}
10387

104-
public void setTimeActiveFormatted(String timeActiveFormatted) {
105-
this.timeActiveFormatted = timeActiveFormatted;
106-
}
107-
108-
public long getTimeStayInMinutes() {
109-
return timeStayInMinutes;
110-
}
111-
112-
public void setTimeStayInMinutes(long timeStayInMinutes) {
113-
this.timeStayInMinutes = timeStayInMinutes;
114-
}
115-
11688
public String getTimeStayFormatted() {
89+
if (timeStayFormatted == null) {
90+
timeStayFormatted = StringHelper.formatDuration(Duration.ofMillis(timeStay));
91+
}
11792
return timeStayFormatted;
11893
}
119-
120-
public void setTimeStayFormatted(String timeStayFormatted) {
121-
this.timeStayFormatted = timeStayFormatted;
122-
}
12394
}

src/main/resources/application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ captcha_public_key=
2222
captcha_private_key=
2323

2424
# Integration settings
25+
integration_tracker_url=https://learnweb.l3s.uni-hannover.de/tracker
2526
integration_tracker_apikey=
27+
integration_tracker_secret=
2628

2729
integration_interweb_url=https://interweb.l3s.uni-hannover.de
2830
integration_interweb_apikey=

src/main/webapp/lw/dashboard/tracker.xhtml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,17 @@
7272
<p:column styleClass="ui-column-title" headerText="#{msg.total_events}" sortBy="#{ts.totalEvents}" sortable="true">
7373
#{ts.totalEvents}
7474
</p:column>
75-
<p:column styleClass="ui-column-title" headerText="#{msg.time_stay}" sortBy="#{ts.timeStayFormatted}" sortable="true">
75+
<p:column styleClass="ui-column-title" headerText="#{msg.time_stay}" sortBy="#{ts.timeStay}" sortable="true">
7676
#{ts.timeStayFormatted}
7777
</p:column>
78-
<p:column styleClass="ui-column-title" headerText="#{msg.time_active}" sortBy="#{ts.timeActiveFormatted}" sortable="true">
78+
<p:column styleClass="ui-column-title" headerText="#{msg.time_active}" sortBy="#{ts.timeActive}" sortable="true">
7979
#{ts.timeActiveFormatted}
8080
</p:column>
8181
<p:column styleClass="ui-column-title" headerText="#{msg.clicks}" sortBy="#{ts.clicks}" sortable="true">
8282
#{ts.clicks}
8383
</p:column>
84-
<p:column styleClass="ui-column-title" headerText="#{msg.keypresses}" sortBy="#{ts.keyPresses}" sortable="true">
85-
#{ts.keyPresses}
84+
<p:column styleClass="ui-column-title" headerText="#{msg.keypresses}" sortBy="#{ts.keypresses}" sortable="true">
85+
#{ts.keypresses}
8686
</p:column>
8787
</p:dataTable>
8888
</h:form>

0 commit comments

Comments
 (0)