Project

General

Profile

1
package eu.dnetlib.uoaorcidservice.services;
2

    
3
import eu.dnetlib.uoaorcidservice.dao.MetricsDAO;
4
import eu.dnetlib.uoaorcidservice.dao.customDAOs.MongoDBUserTokensDAOCustom;
5
import eu.dnetlib.uoaorcidservice.dao.customDAOs.MongoDBWorkDAOCustom;
6
import eu.dnetlib.uoaorcidservice.entities.Metrics;
7
import org.apache.log4j.Logger;
8
import org.springframework.beans.factory.annotation.Autowired;
9
import org.springframework.beans.factory.annotation.Qualifier;
10
import org.springframework.scheduling.annotation.EnableScheduling;
11
import org.springframework.scheduling.annotation.Scheduled;
12
import org.springframework.stereotype.Service;
13

    
14
import java.time.Instant;
15
import java.util.*;
16

    
17

    
18
@EnableScheduling
19
@Service
20
public class MetricsService {
21
    private final Logger log = Logger.getLogger(this.getClass());
22

    
23
    @Autowired
24
    @Qualifier("mongoDBWorkDAO")
25
    private MongoDBWorkDAOCustom workDAO;
26

    
27
    @Autowired
28
    @Qualifier("mongoDBUserTokensDAO")
29
    private MongoDBUserTokensDAOCustom userTokensDAO;
30

    
31
    @Autowired
32
    private MetricsDAO metricsDAO;
33

    
34
    public List<Object> countWorksPerDashboard() {
35
        return workDAO.worksPerDashboard();
36
    }
37

    
38
    public List<Object> countWorksPerYear() {
39
        return workDAO.worksPerYear();
40
    }
41

    
42
    public List<Object> countWorksPerYearAndMonth() {
43
        return workDAO.worksPerYearAndMonth();
44
    }
45

    
46
    public List<Object> countWorksPerOrcid() {
47
        return workDAO.worksPerOrcid();
48
    }
49

    
50
    public List<Object> countUniqueUsersWithLinksPerMonth() {
51
        return workDAO.uniqueUsersWithLinksPerMonth();
52
    }
53

    
54
    public List<Object> countUniqueUsersWithLinksPerYear() {
55
        return workDAO.uniqueUsersWithLinksPerYear();
56
    }
57

    
58
    public List<Object> countNewUsersPerMonth() {
59
        return userTokensDAO.newUsersPerMonth();
60
    }
61

    
62
    public List<Object> countNewUsersPerYear() {
63
        return userTokensDAO.newUsersPerYear();
64
    }
65

    
66
    public List<Object> countTokensPerOrcid() {
67
        return userTokensDAO.tokensPerOrcid();
68
    }
69

    
70
    public List<Object> countTotalUniqueUsers() {
71
        return userTokensDAO.totalUniqueUsers();
72
    }
73

    
74
    public List<Object> countTotalWorks() {
75
        return workDAO.totalWorks();
76
    }
77

    
78

    
79
    // every day at midnight
80
    @Scheduled(cron = "0 0 0 * * ?")
81
//    // every 5 mins for testing
82
//    @Scheduled(cron = "0 0/5 * * * *")
83
    public Metrics calculateMetrics() {
84
        log.info("Calculate metrics and add them in DB");
85

    
86
//        Optional<Metrics> oldMetrics = metricsDAO.findById("current");
87
//        if(oldMetrics.isPresent()) {
88
//            oldMetrics.get().setId("previous");
89
//            metricsDAO.save(oldMetrics.get());
90
//        }
91

    
92
        Metrics metrics = new Metrics();
93
        metrics.setId("current");
94
        List<Object> totalWorks = countTotalWorks();
95
        if(totalWorks != null && totalWorks.get(0) != null) {
96
            Map<String, Integer> works = (HashMap<String, Integer>) totalWorks.get(0);
97
            metrics.setTotal_works(works.get("works"));
98
        } else {
99
            metrics.setTotal_works(-1);
100
            return metrics;
101
        }
102
        List<Object> totalUsers = countTotalUniqueUsers();
103
        if(totalUsers != null && totalUsers.get(0) != null) {
104
            Map<String, Integer> users = (HashMap<String, Integer>) totalUsers.get(0);
105
            metrics.setTotal_users(users.get("users"));
106
        } else {
107
            metrics.setTotal_users(-1);
108
            return metrics;
109
        }
110
//        metrics.setWorks_per_month(countWorksPerYearAndMonth());
111
        List<Object> works_per_dashboard = countWorksPerDashboard();
112
        for(Object dashboardWorksObj : works_per_dashboard) {
113
            Map<String, Object> dashboardWorks = (HashMap<String, Object>) dashboardWorksObj;
114
            String[] dashboard_elements = ((String) dashboardWorks.get("dashboard")).split("_", 2);
115
            dashboardWorks.put("environment", dashboard_elements[0]);
116
            dashboardWorks.put("dashboard", dashboard_elements[1]);
117
//            if(dashboard_elements.length > 2) {
118
//                dashboardWorks.put("dashboardName", dashboard_elements[2]);
119
//            }
120
        }
121
        metrics.setWorks_per_dashboard(works_per_dashboard);
122
        metrics.setDate(new Date());
123

    
124
        metricsDAO.save(metrics);
125

    
126
//        Total works linked: http://duffy.di.uoa.gr:8080/uoa-orcid-service/report/totalWorks
127
//        Total users: (unique/ per orcid): http://duffy.di.uoa.gr:8080/uoa-orcid-service/report/totalUniqueUsers
128
//        Works linked per month: http://duffy.di.uoa.gr:8080/uoa-orcid-service/report/worksPerYearAndMonth (not needed?)
129
//        Works linked per portal (not only explore): http://duffy.di.uoa.gr:8080/uoa-orcid-service/report/worksPerDashboard
130
        return metrics;
131
    }
132

    
133
    public String getMetrics() {
134
//        # TYPE aai_registered_users_total gauge
135
//        aai_registered_users_total 50
136
//# TYPE aai_logins_total counter
137
//        aai_logins_total 1742
138
//# TYPE aai_api_requests_total counter
139
//        aai_api_requests_total 0
140
//        aai_last_metrics_updater_run_timestamp_seconds 1619157852
141

    
142
        Optional<Metrics> metrics_optional = metricsDAO.findById("current");
143
        if(!metrics_optional.isPresent()) {
144
            return null;
145
        }
146
        Metrics metrics = metrics_optional.get();
147
        String response = "";
148

    
149
//        response += "# TYPE explore_orcid_works_total gauge\n";
150
//        response += "explore_orcid_works_total "+metrics.getTotal_works() + "\n";
151

    
152
        response += "# TYPE orcid_users gauge\n";
153
        response += "orcid_users "+metrics.getTotal_users() + "\n";
154

    
155

    
156
//        if(metrics.getWorks_per_month() != null) {
157
//            for(Object monthlyWorksObj : metrics.getWorks_per_month()) {
158
//                Map<String, Integer> monthlyWorks = (HashMap<String, Integer>) monthlyWorksObj;
159
//                response += "# TYPE orcid_total_works_"+monthlyWorks.get("month")+"_"+monthlyWorks.get("year")+" counter\n";
160
//                response += "orcid_total_works_"+monthlyWorks.get("month")+"_"+monthlyWorks.get("year")+" "+monthlyWorks.get("works") + "\n";
161
//
162
//            }
163
//        }
164

    
165
        if(metrics.getWorks_per_dashboard() != null) {
166
            // 2nd approach
167
//            Map<String, Integer> worksPerEnvironment = new HashMap<>();
168
            // 3rd approach
169
            Map<String, Integer> worksPerDashboard = new HashMap<>();
170
            // 1st approach
171
//            response += "# TYPE orcid_works gauge\n";
172

    
173
            for(Object dashboardWorksObj : metrics.getWorks_per_dashboard()) {
174
                Map<String, Object> dashboardWorks = (HashMap<String, Object>) dashboardWorksObj;
175
                // 1st approach - e.g. orcid_works{envoronment="production" portal="explore"} 10
176
//                response += "orcid_works{environment=\""+dashboardWorks.get("environment")+"\" portal=\""+dashboardWorks.get("dashboard")+"\"}"+" "+dashboardWorks.get("works") + "\n";
177

    
178
                // 2nd approach - e.g. explore_orcid_works_total{envoronment="production"} 10
179
//                if(worksPerEnvironment.containsKey(dashboardWorks.get("environment"))) {
180
//                    int worksSoFar = worksPerEnvironment.get(dashboardWorks.get("environment"));
181
//                    worksPerEnvironment.put((String)dashboardWorks.get("environment"), (Integer) dashboardWorks.get("works") + worksSoFar);
182
//                } else {
183
//                    worksPerEnvironment.put((String)dashboardWorks.get("environment"), (Integer) dashboardWorks.get("works"));
184
//                }
185

    
186
                // 3rd approach - e.g. orcid_works{portal="explore"} 10
187
                if(worksPerDashboard.containsKey(dashboardWorks.get("dashboard"))) {
188
                    int worksSoFar = worksPerDashboard.get(dashboardWorks.get("dashboard"));
189
                    worksPerDashboard.put((String)dashboardWorks.get("dashboard"), (Integer) dashboardWorks.get("works") + worksSoFar);
190
                } else {
191
                    worksPerDashboard.put((String)dashboardWorks.get("dashboard"), (Integer) dashboardWorks.get("works"));
192
                }
193
            }
194
            // 2nd approach
195
//            response += "# TYPE explore_orcid_works_total gauge\n";
196
//            for(Map.Entry<String, Integer> envWorks : worksPerEnvironment.entrySet()) {
197
//                response += "explore_orcid_works_total{environment=\""+envWorks.getKey()+"\"} "+envWorks.getValue() + "\n";
198
//            }
199

    
200
            // 3rd approach
201
            response += "# TYPE orcid_works gauge\n";
202
            for(Map.Entry<String, Integer> envWorks : worksPerDashboard.entrySet()) {
203
                response += "orcid_works{portal=\""+envWorks.getKey()+"\"} "+envWorks.getValue() + "\n";
204
            }
205
        }
206

    
207
        Instant instant = metrics.getDate().toInstant();
208
        response += "orcid_last_metrics_updater_run_timestamp_seconds "+instant.getEpochSecond()+"\n";
209

    
210
        return response;
211
    }
212
}
(1-1/3)