Project

General

Profile

1
package eu.dnetlib.usagestats.export;
2

    
3
import java.io.*;
4
//import java.io.BufferedReader;
5
//import java.io.InputStreamReader;
6
import java.net.URL;
7
import java.net.URLConnection;
8
import java.sql.ResultSet;
9
import java.text.SimpleDateFormat;
10
import java.util.Date;
11
import java.util.Calendar;
12

    
13
import java.sql.Connection;
14
import java.sql.DriverManager;
15
import java.sql.PreparedStatement;
16
import java.sql.Statement;
17

    
18
import org.json.simple.JSONArray;
19
import org.json.simple.JSONObject;
20
import org.json.simple.parser.JSONParser;
21

    
22
import org.apache.log4j.Logger;
23

    
24
/**
25
 * Created by tsampikos on 28/3/2017.
26
 */
27
public class IrusStats {
28
     private final String dbUrl;
29
    private final String dbSchema;
30
    private final String dbUserName;
31
    private final String dbPassword;
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 dbUrl, String dbUsername, String dbPassword) throws Exception {
39
        this.dbUrl = dbUrl;
40
        this.dbSchema = "shadow";
41
        this.dbUserName = dbUsername;
42
        this.dbPassword = dbPassword;
43

    
44
        connectDB();
45
        createTables();
46
    }
47

    
48
    private void connectDB() throws Exception {
49
        try {
50
            Class.forName("org.postgresql.Driver");
51
            conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);
52

    
53
            stmt = conn.createStatement();
54
            String sqlSetSearchPath = "SET search_path TO " + dbSchema + ";";
55
            stmt.executeUpdate(sqlSetSearchPath);
56

    
57
            log.info("Opened database successfully");
58

    
59
        } catch (Exception e) {
60
            log.error("Connect to db failed: " + e);
61
            throw new Exception("Failed to connect to db: " + e.toString(), e);
62
        }
63
    }
64

    
65
    private void createTables() throws Exception {
66
        try {
67

    
68
            stmt = conn.createStatement();
69
            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));";
70
            stmt.executeUpdate(sqlCreateTableSushiLog);
71

    
72
            stmt.executeUpdate("CREATE TABLE IF NOT EXISTS public.sushilog(source TEXT, repository TEXT, rid TEXT, date TEXT, metric_type TEXT, count INT, PRIMARY KEY(source, repository, rid, date, metric_type));");
73

    
74
            String sqlCopyPublicSushiLog="INSERT INTO sushilog SELECT * FROM public.sushilog;";
75
            stmt.executeUpdate(sqlCopyPublicSushiLog);
76

    
77
            String sqlcreateRuleSushiLog = "CREATE OR REPLACE RULE ignore_duplicate_inserts AS " +
78
                " ON INSERT TO sushilog " +
79
                " WHERE (EXISTS ( SELECT sushilog.source, sushilog.repository," +
80
                "sushilog.rid, sushilog.date " +
81
                "FROM sushilog " +
82
                "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;";
83
            stmt.executeUpdate(sqlcreateRuleSushiLog);
84

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

    
94
    public void irusStats() throws Exception {
95
        if (conn.isClosed())
96
            connectDB();
97

    
98
        stmt = conn.createStatement();
99
        conn.setAutoCommit(false);
100

    
101
        //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'";
102
        //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'";
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 FROM sushilog s, datasource_oids d, result_oids ro WHERE s.repository=d.orid AND s.oai=ro.orid AND metric_type='ft_total';";
104
        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 sushilog s, datasource_oids d, result_oids ro WHERE s.repository=d.orid AND s.rid=ro.orid AND metric_type='ft_total' AND s.source='IRUS-UK';";
105
        stmt.executeUpdate(sql);
106

    
107

    
108
        stmt.close();
109
        conn.commit();
110
        conn.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

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

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

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

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

    
148
    private void processIrusIRReport(String opendoar) throws Exception {
149
        if (conn.isClosed())
150
            connectDB();
151

    
152
        conn.setAutoCommit(false);
153

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

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

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

    
164
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
165
        PreparedStatement st = conn.prepareStatement("SELECT max(date) FROM public.sushilog WHERE repository=?;");
166
        st.setString(1, "opendoar____::" + opendoar);
167
        ResultSet rs_date = st.executeQuery();
168
        while(rs_date.next()){
169
            if(rs_date.getString(1) != null && !rs_date.getString(1).equals("null") && !rs_date.getString(1).equals("")) {
170
                start.setTime(sdf.parse(rs_date.getString(1)));
171
            }
172
        }
173
        rs_date.close();
174

    
175
        PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO sushilog (source, repository, rid, date, metric_type, count) VALUES (?,?,?,?,?,?)");
176
        int batch_size = 0;
177

    
178
        while(start.before(end)){
179
            //log.info("date: " + simpleDateFormat.format(start.getTime()));
180
            String reportUrl = "https://irus.jisc.ac.uk/api/sushilite/v1_7/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=";
181
            start.add(Calendar.MONTH, 1);
182

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

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

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

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

    
243
        preparedStatement.executeBatch();
244
        conn.commit();
245
        conn.close();
246
    }
247

    
248
    private String getJson(String url,String username, String password) throws Exception {
249
        //String cred=username+":"+password;
250
        //String encoded = new sun.misc.BASE64Encoder().encode (cred.getBytes());
251
        try {
252
            URL website = new URL(url);
253
            URLConnection connection = website.openConnection();
254
            //connection.setRequestProperty ("Authorization", "Basic "+encoded);
255
            StringBuilder response;
256
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
257
                response = new StringBuilder();
258
                String inputLine;
259
                while ((inputLine = in.readLine()) != null) {
260
                    response.append(inputLine);
261
                    response.append("\n");
262
                }
263
            }
264
            return response.toString();
265
        }catch (Exception e){
266
            log.error("Failed to get URL", e);
267
            return null;
268
        }
269
    }
270

    
271
    /*
272
    private void flushString(String data, String destination) throws Exception {
273
        FSDataOutputStream fin;
274
        try {
275
            FileSystem fs = FileSystem.get(new Configuration());
276
            fin = fs.create(new Path(destination), true);
277
            fin.write(data.getBytes());
278
            fin.close();
279
        } catch (Exception e) {
280
            log.error("Failed  to write exported data to a file : ", e);
281
            throw new Exception("Failed  to write exported data to a file : " + e.toString(), e);
282
        }
283
    }
284
    */
285
}
(1-1/5)