Project

General

Profile

1
package eu.dnetlib.usagestats.export;
2
/**
3
 *
4
 * @author dpie
5
 */
6
import java.io.*;
7
//import java.io.BufferedReader;
8
//import java.io.InputStreamReader;
9
import java.net.URL;
10
import java.net.URLConnection;
11
import java.sql.ResultSet;
12
import java.text.SimpleDateFormat;
13
import java.util.Date;
14
import java.util.Calendar;
15

    
16
import java.sql.Connection;
17
import java.sql.PreparedStatement;
18
import java.sql.Statement;
19

    
20
import org.json.simple.JSONArray;
21
import org.json.simple.JSONObject;
22
import org.json.simple.parser.JSONParser;
23

    
24
import org.apache.log4j.Logger;
25

    
26
/**
27
 * Created by dpie on 20/01/2020.
28
 */
29
public class IrusStats {
30

    
31
    private String irusUKURL;
32

    
33
//    private Connection conn = null;
34
//    private Statement stmt = null;
35

    
36
    private final Logger log = Logger.getLogger(this.getClass());
37

    
38
    public IrusStats(String irusUKURL) throws Exception {
39
        this.irusUKURL = irusUKURL;
40
        createTables();
41
        createTmpTables();
42
    }
43

    
44
       private void createTables() throws Exception {
45
        try {
46

    
47
            Statement  stmt = ConnectDB.getConnection().createStatement();
48
            String sqlCreateTableSushiLog = "CREATE TABLE IF NOT EXISTS sushilog(source TEXT, repository TEXT, rid TEXT, date TEXT, metric_type TEXT, count INT, PRIMARY KEY(source, repository, rid, date, metric_type));";
49
            stmt.executeUpdate(sqlCreateTableSushiLog);
50
            String sqlcreateRuleSushiLog = "CREATE OR REPLACE RULE ignore_duplicate_inserts AS "
51
                    + " ON INSERT TO sushilog "
52
                    + " WHERE (EXISTS ( SELECT sushilog.source, sushilog.repository,"
53
                    + "sushilog.rid, sushilog.date "
54
                    + "FROM sushilog "
55
                    + "WHERE sushilog.source = new.source AND sushilog.repository = new.repository AND sushilog.rid = new.rid AND sushilog.date = new.date AND sushilog.metric_type = new.metric_type)) DO INSTEAD NOTHING;";
56
            stmt.executeUpdate(sqlcreateRuleSushiLog);
57
            String createSushiIndex = "create index if not exists sushilog_duplicates on sushilog(source, repository, rid, date, metric_type);";
58
            stmt.executeUpdate(createSushiIndex);
59

    
60
            stmt.close();
61
            ConnectDB.getConnection().close();
62
            log.info("Sushi Tables Created");
63
        } catch (Exception e) {
64
            log.error("Failed to create tables: " + e);
65
            throw new Exception("Failed to create tables: " + e.toString(), e);
66
        }
67
    }
68

    
69
    private void createTmpTables() throws Exception {
70
        try {
71

    
72
            Statement stmt = ConnectDB.getConnection().createStatement();
73
            String sqlCreateTableSushiLog = "CREATE TABLE IF NOT EXISTS sushilogtmp(source TEXT, repository TEXT, rid TEXT, date TEXT, metric_type TEXT, count INT, PRIMARY KEY(source, repository, rid, date, metric_type));";
74
            stmt.executeUpdate(sqlCreateTableSushiLog);
75

    
76
            //stmt.executeUpdate("CREATE TABLE IF NOT EXISTS public.sushilog AS TABLE sushilog;");
77
            //String sqlCopyPublicSushiLog = "INSERT INTO sushilog SELECT * FROM public.sushilog;";
78
            //stmt.executeUpdate(sqlCopyPublicSushiLog);
79
            String sqlcreateRuleSushiLog = "CREATE OR REPLACE RULE ignore_duplicate_inserts AS "
80
                    + " ON INSERT TO sushilogtmp "
81
                    + " WHERE (EXISTS ( SELECT sushilogtmp.source, sushilogtmp.repository,"
82
                    + "sushilogtmp.rid, sushilogtmp.date "
83
                    + "FROM sushilogtmp "
84
                    + "WHERE sushilogtmp.source = new.source AND sushilogtmp.repository = new.repository AND sushilogtmp.rid = new.rid AND sushilogtmp.date = new.date AND sushilogtmp.metric_type = new.metric_type)) DO INSTEAD NOTHING;";
85
            stmt.executeUpdate(sqlcreateRuleSushiLog);
86

    
87
            stmt.close();
88
            ConnectDB.getConnection().close();
89
            log.info("Sushi Tmp Tables Created");
90
        } catch (Exception e) {
91
            log.error("Failed to create tables: " + e);
92
            throw new Exception("Failed to create tables: " + e.toString(), e);
93
        }
94
    }
95

    
96
    public void irusStats() throws Exception {
97
        Statement stmt = ConnectDB.getConnection().createStatement();
98
        ConnectDB.getConnection().setAutoCommit(false);
99

    
100
        //String sql = "INSERT INTO sushi_result_downloads SELECT s.source, d.id AS repository, ro.id, s.date, s.count FROM sushilog s, datasource_oids d, result_oids ro WHERE s.repository=d.orid AND s.oai=ro.orid AND metric_type='ft_total'";
101
        //String sql = "SELECT s.source, d.id AS repository_id, ro.id as result_id, extract('year' from s.date::date) ||'/'|| LPAD(CAST(extract('month' from s.date::date) AS VARCHAR), 2, '0') as date, s.count INTO downloads_stats FROM sushilog s, datasource_oids d, result_oids ro WHERE s.repository=d.orid AND s.oai=ro.orid AND metric_type='ft_total'";
102
        //String sql = "INSERT INTO downloads_stats SELECT s.source, d.id AS repository_id, ro.id as result_id, extract('year' from s.date::date) ||'/'|| LPAD(CAST(extract('month' from s.date::date) AS VARCHAR), 2, '0') as date, s.count FROM sushilog s, datasource_oids d, result_oids ro WHERE s.repository=d.orid AND s.oai=ro.orid AND metric_type='ft_total';";
103
        String sql = "INSERT INTO downloads_stats SELECT s.source, d.id AS repository_id, ro.id as result_id, extract('year' from s.date::date) ||'/'|| LPAD(CAST(extract('month' from s.date::date) AS VARCHAR), 2, '0') as date, s.count, '0' FROM sushilogtmp s, public.datasource_oids d, public.result_oids ro WHERE s.repository=d.orid AND s.rid=ro.orid AND metric_type='ft_total' AND s.source='IRUS-UK';";
104
        stmt.executeUpdate(sql);
105

    
106
        sql = "Insert into sushilog select * from sushilogtmp;";
107
        stmt.executeUpdate(sql);
108
        
109
        ConnectDB.getConnection().commit();
110
        ConnectDB.getConnection().close();
111
    }
112

    
113
    public void processIrusRRReport() throws Exception {
114
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM");
115
        //String reportUrl = "https://irus.jisc.ac.uk" + "/api/sushilite/v1_7/GetReport/?Report=RR1&Release=4&RequestorID=OpenAIRE&BeginDate=2016-01&EndDate=" + simpleDateFormat.format(new Date()) + "&RepositoryIdentifier=&ItemDataType=&NewJiscBand=&Granularity=Monthly&Callback=";
116
        String reportUrl = irusUKURL + "GetReport/?Report=RR1&Release=4&RequestorID=OpenAIRE&BeginDate=2016-01&EndDate=" + simpleDateFormat.format(new Date()) + "&RepositoryIdentifier=&ItemDataType=&NewJiscBand=&Granularity=Monthly&Callback=";
117

    
118
        log.info("Getting Irus report: " + reportUrl);
119

    
120
        String text = getJson(reportUrl, "", "");
121

    
122
        log.info("Report: " + text);
123

    
124
        JSONParser parser = new JSONParser();
125
        JSONObject jsonObject = (JSONObject) parser.parse(text);
126
        jsonObject = (JSONObject) jsonObject.get("ReportResponse");
127
        jsonObject = (JSONObject) jsonObject.get("Report");
128
        jsonObject = (JSONObject) jsonObject.get("Report");
129
        jsonObject = (JSONObject) jsonObject.get("Customer");
130
        JSONArray jsonArray = (JSONArray) jsonObject.get("ReportItems");
131
        int i = 0;
132
        for (Object aJsonArray : jsonArray) {
133
            JSONObject jsonObjectRow = (JSONObject) aJsonArray;
134
            JSONArray itemIdentifier = (JSONArray) jsonObjectRow.get("ItemIdentifier");
135
            for (Object identifier : itemIdentifier) {
136
                JSONObject opendoar = (JSONObject) identifier;
137
                if (opendoar.get("Type").toString().equals("OpenDOAR")) {
138
                    //System.out.println(i + ": " + opendoar.get("Value").toString());
139
                    log.info(i + ": " + opendoar.get("Value").toString());
140
                    i++;
141
                    processIrusIRReport(opendoar.get("Value").toString());
142
                    break;
143
                }
144
            }
145
            //break;
146
        }
147
    }
148

    
149
    private void processIrusIRReport(String opendoar) throws Exception {
150
        System.out.println(opendoar);
151
        ConnectDB.getConnection().setAutoCommit(false);
152

    
153
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM");
154

    
155
        Calendar start = Calendar.getInstance();
156
        start.set(Calendar.YEAR, 2016);
157
        start.set(Calendar.MONTH, Calendar.JANUARY);
158
        //start.setTime(simpleDateFormat.parse("2016-01"));
159

    
160
        Calendar end = Calendar.getInstance();
161
        end.add(Calendar.DAY_OF_MONTH, -1);
162

    
163
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
164
        PreparedStatement st = ConnectDB.getConnection().prepareStatement("SELECT max(date) FROM sushilog WHERE repository=?;");
165
        st.setString(1, "opendoar____::" + opendoar);
166
        ResultSet rs_date = st.executeQuery();
167
        while (rs_date.next()) {
168
            if (rs_date.getString(1) != null && !rs_date.getString(1).equals("null") && !rs_date.getString(1).equals("")) {
169
                start.setTime(sdf.parse(rs_date.getString(1)));
170
            }
171
        }
172
        rs_date.close();
173
        PreparedStatement preparedStatement = ConnectDB.getConnection().prepareStatement("INSERT INTO sushilogtmp (source, repository, rid, date, metric_type, count) VALUES (?,?,?,?,?,?)");
174
        int batch_size = 0;
175

    
176
        while (start.before(end)) {
177
            //log.info("date: " + simpleDateFormat.format(start.getTime()));
178
            String reportUrl = this.irusUKURL+"GetReport/?Report=IR1&Release=4&RequestorID=OpenAIRE&BeginDate=" + simpleDateFormat.format(start.getTime()) + "&EndDate=" + simpleDateFormat.format(start.getTime()) + "&RepositoryIdentifier=opendoar%3A" + opendoar + "&ItemIdentifier=&ItemDataType=&hasDOI=&Granularity=Monthly&Callback=";
179
            start.add(Calendar.MONTH, 1);
180

    
181
            String text = getJson(reportUrl, "", "");
182
            if (text == null) {
183
                continue;
184
            }
185

    
186
            JSONParser parser = new JSONParser();
187
            JSONObject jsonObject = (JSONObject) parser.parse(text);
188
            jsonObject = (JSONObject) jsonObject.get("ReportResponse");
189
            jsonObject = (JSONObject) jsonObject.get("Report");
190
            jsonObject = (JSONObject) jsonObject.get("Report");
191
            jsonObject = (JSONObject) jsonObject.get("Customer");
192
            JSONArray jsonArray = (JSONArray) jsonObject.get("ReportItems");
193
            if (jsonArray == null) {
194
                continue;
195
            }
196
            String oai = "";
197
            for (Object aJsonArray : jsonArray) {
198
                JSONObject jsonObjectRow = (JSONObject) aJsonArray;
199
                JSONArray itemIdentifier = (JSONArray) jsonObjectRow.get("ItemIdentifier");
200
                for (Object identifier : itemIdentifier) {
201
                    JSONObject oaiPmh = (JSONObject) identifier;
202
                    if (oaiPmh.get("Type").toString().equals("OAI")) {
203
                        oai = oaiPmh.get("Value").toString();
204
                        //System.out.println("OAI: " + oai);
205
                        break;
206
                    }
207
                }
208

    
209
                JSONArray itemPerformance = (JSONArray) jsonObjectRow.get("ItemPerformance");
210
                String period;
211
                String type;
212
                String count;
213
                for (Object perf : itemPerformance) {
214
                    JSONObject performance = (JSONObject) perf;
215
                    JSONObject periodObj = (JSONObject) performance.get("Period");
216
                    period = periodObj.get("Begin").toString();
217
                    JSONObject instanceObj = (JSONObject) performance.get("Instance");
218
                    type = instanceObj.get("MetricType").toString();
219
                    count = instanceObj.get("Count").toString();
220
                    //System.out.println(oai + " : " + period + " : " + count);
221

    
222
                    preparedStatement.setString(1, "IRUS-UK");
223
                    preparedStatement.setString(2, "opendoar____::" + opendoar);
224
                    preparedStatement.setString(3, oai);
225
                    preparedStatement.setString(4, period);
226
                    preparedStatement.setString(5, type);
227
                    preparedStatement.setInt(6, Integer.parseInt(count));
228
                    preparedStatement.addBatch();
229
                    batch_size++;
230
                    if (batch_size == 10000) {
231
                        preparedStatement.executeBatch();
232
                        ConnectDB.getConnection().commit();
233
                        batch_size = 0;
234
                    }
235
                }
236
                //break;
237
            }
238
            //break;
239
        }
240

    
241
        preparedStatement.executeBatch();
242
        ConnectDB.getConnection().commit();
243
        ConnectDB.getConnection().close();
244
    }
245

    
246
    public void processIrusIRReport(String opendoar, String startDate) throws Exception {
247
        ConnectDB.getConnection().setAutoCommit(false);
248

    
249
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM");
250

    
251
        Calendar start = Calendar.getInstance();
252
        start.set(Calendar.YEAR, 2016);
253
        start.set(Calendar.MONTH, Calendar.JANUARY);
254
        //start.setTime(simpleDateFormat.parse("2016-01"));
255

    
256
        Calendar end = Calendar.getInstance();
257
        end.add(Calendar.DAY_OF_MONTH, -1);
258

    
259
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
260
        start.setTime(sdf.parse(startDate));
261

    
262
        String createTablesQuery = "-- Table: shadow.sushilog" + opendoar + "\n"
263
                + "\n"
264
                + "-- DROP TABLE shadow.sushilog" + opendoar + ";\n"
265
                + "\n"
266
                + "CREATE TABLE shadow.sushilog" + opendoar + "\n"
267
                + "(\n"
268
                + "    source text COLLATE pg_catalog.\"default\" NOT NULL,\n"
269
                + "    repository text COLLATE pg_catalog.\"default\" NOT NULL,\n"
270
                + "    rid text COLLATE pg_catalog.\"default\" NOT NULL,\n"
271
                + "    date text COLLATE pg_catalog.\"default\" NOT NULL,\n"
272
                + "    metric_type text COLLATE pg_catalog.\"default\" NOT NULL,\n"
273
                + "    count integer,\n"
274
                + "    CONSTRAINT sushilog" + opendoar + "_pkey PRIMARY KEY (source, repository, rid, date, metric_type)\n"
275
                + "        USING INDEX TABLESPACE index_storage\n"
276
                + ")\n"
277
                + "\n"
278
                + "TABLESPACE pg_default;\n"
279
                + "\n"
280
                + "ALTER TABLE shadow.sushilog" + opendoar + "\n"
281
                + "    OWNER to sqoop;\n"
282
                + "\n"
283
                + "-- Rule: ignore_duplicate_inserts ON shadow.sushilog" + opendoar + "\n"
284
                + "\n"
285
                + "-- DROP Rule ignore_duplicate_inserts ON shadow.sushilog" + opendoar + ";\n"
286
                + "\n"
287
                + "CREATE OR REPLACE RULE ignore_duplicate_inserts AS\n"
288
                + "    ON INSERT TO shadow.sushilog" + opendoar + "\n"
289
                + "    WHERE (EXISTS ( SELECT sushilog" + opendoar + ".source,\n"
290
                + "            sushilog" + opendoar + ".repository,\n"
291
                + "            sushilog" + opendoar + ".rid,\n"
292
                + "            sushilog" + opendoar + ".date\n"
293
                + "           FROM sushilog" + opendoar + "\n"
294
                + "          WHERE sushilog" + opendoar + ".source = new.source AND sushilog" + opendoar + ".repository = new.repository AND sushilog" + opendoar + ".rid = new.rid AND sushilog" + opendoar + ".date = new.date AND sushilog" + opendoar + ".metric_type = new.metric_type))\n"
295
                + "    DO INSTEAD\n"
296
                + "NOTHING;";
297

    
298
        Statement stCreateTables = ConnectDB.getConnection().createStatement();
299
        stCreateTables.execute(createTablesQuery);
300
        ConnectDB.getConnection().commit();
301

    
302
        PreparedStatement preparedStatement = ConnectDB.getConnection().prepareStatement("INSERT INTO sushilog" + opendoar + " (source, repository, rid, date, metric_type, count) VALUES (?,?,?,?,?,?)");
303
        int batch_size = 0;
304

    
305
        while (start.before(end)) {
306
            //log.info("date: " + simpleDateFormat.format(start.getTime()));
307
            String reportUrl = "https://irus.jisc.ac.uk/api/sushilite/v1_7/GetReport/?Report=IR1&Release=4&RequestorID=OpenAIRE&BeginDate=" + simpleDateFormat.format(start.getTime()) + "&EndDate=2019-10-31&RepositoryIdentifier=opendoar%3A" + opendoar + "&ItemIdentifier=&ItemDataType=&hasDOI=&Granularity=Monthly&Callback=";
308
            start.add(Calendar.MONTH, 1);
309

    
310
            String text = getJson(reportUrl, "", "");
311
            if (text == null) {
312
                continue;
313
            }
314

    
315
            JSONParser parser = new JSONParser();
316
            JSONObject jsonObject = (JSONObject) parser.parse(text);
317
            jsonObject = (JSONObject) jsonObject.get("ReportResponse");
318
            jsonObject = (JSONObject) jsonObject.get("Report");
319
            jsonObject = (JSONObject) jsonObject.get("Report");
320
            jsonObject = (JSONObject) jsonObject.get("Customer");
321
            JSONArray jsonArray = (JSONArray) jsonObject.get("ReportItems");
322
            if (jsonArray == null) {
323
                continue;
324
            }
325
            String oai = "";
326
            for (Object aJsonArray : jsonArray) {
327
                JSONObject jsonObjectRow = (JSONObject) aJsonArray;
328
                JSONArray itemIdentifier = (JSONArray) jsonObjectRow.get("ItemIdentifier");
329
                for (Object identifier : itemIdentifier) {
330
                    JSONObject oaiPmh = (JSONObject) identifier;
331
                    if (oaiPmh.get("Type").toString().equals("OAI")) {
332
                        oai = oaiPmh.get("Value").toString();
333
                        //System.out.println("OAI: " + oai);
334
                        break;
335
                    }
336
                }
337

    
338
                JSONArray itemPerformance = (JSONArray) jsonObjectRow.get("ItemPerformance");
339
                String period;
340
                String type;
341
                String count;
342
                for (Object perf : itemPerformance) {
343
                    JSONObject performance = (JSONObject) perf;
344
                    JSONObject periodObj = (JSONObject) performance.get("Period");
345
                    period = periodObj.get("Begin").toString();
346
                    JSONObject instanceObj = (JSONObject) performance.get("Instance");
347
                    type = instanceObj.get("MetricType").toString();
348
                    count = instanceObj.get("Count").toString();
349
                    //System.out.println(oai + " : " + period + " : " + count);
350

    
351
                    preparedStatement.setString(1, "IRUS-UK");
352
                    preparedStatement.setString(2, "opendoar____::" + opendoar);
353
                    preparedStatement.setString(3, oai);
354
                    preparedStatement.setString(4, period);
355
                    preparedStatement.setString(5, type);
356
                    preparedStatement.setInt(6, Integer.parseInt(count));
357
                    preparedStatement.addBatch();
358
                    batch_size++;
359
                    if (batch_size == 10000) {
360
                        preparedStatement.executeBatch();
361
                        ConnectDB.getConnection().commit();
362
                        batch_size = 0;
363
                    }
364
                }
365
                //break;
366
            }
367
            //break;
368
        }
369

    
370
        preparedStatement.executeBatch();
371
        ConnectDB.getConnection().commit();
372
        ConnectDB.getConnection().close();
373
    }
374

    
375
    private String getJson(String url, String username, String password) throws Exception {
376
        //String cred=username+":"+password;
377
        //String encoded = new sun.misc.BASE64Encoder().encode (cred.getBytes());
378
        try {
379
            URL website = new URL(url);
380
            URLConnection connection = website.openConnection();
381
            //connection.setRequestProperty ("Authorization", "Basic "+encoded);
382
            StringBuilder response;
383
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
384
                response = new StringBuilder();
385
                String inputLine;
386
                while ((inputLine = in.readLine()) != null) {
387
                    response.append(inputLine);
388
                    response.append("\n");
389
                }
390
            }
391
            return response.toString();
392
        } catch (Exception e) {
393
            log.error("Failed to get URL", e);
394
            return null;
395
        }
396
    }
397
}
(3-3/9)