Project

General

Profile

1
package eu.dnetlib.repo.manager.server.services;
2

    
3
import com.fasterxml.jackson.databind.ObjectMapper;
4
import com.unboundid.util.Base64;
5
import eu.dnetlib.domain.data.PiwikInfo;
6
import eu.dnetlib.domain.data.Repository;
7
import eu.dnetlib.domain.data.RepositoryInterface;
8
import eu.dnetlib.domain.enabling.Vocabulary;
9
import eu.dnetlib.domain.functionality.UserProfile;
10
import eu.dnetlib.gwt.server.service.SpringGwtRemoteServiceServlet;
11
import eu.dnetlib.repo.manager.client.services.RepositoryService;
12
import eu.dnetlib.repo.manager.server.utils.EmailUtils;
13
import eu.dnetlib.repo.manager.server.utils.LocalVocabularies;
14
import eu.dnetlib.repo.manager.service.controllers.RepositoryApi;
15
import eu.dnetlib.repo.manager.shared.*;
16
import eu.dnetlib.repos.RepoApi;
17
import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
18
import org.apache.commons.codec.digest.DigestUtils;
19
import org.apache.commons.lang.StringEscapeUtils;
20
import org.apache.commons.lang.WordUtils;
21
import org.apache.log4j.Logger;
22
import org.json.JSONException;
23
import org.springframework.beans.factory.annotation.Autowired;
24
import org.springframework.beans.factory.annotation.Value;
25
import org.springframework.core.ParameterizedTypeReference;
26
import org.springframework.dao.EmptyResultDataAccessException;
27
import org.springframework.http.HttpMethod;
28
import org.springframework.http.ResponseEntity;
29
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
30
import org.springframework.scheduling.annotation.Scheduled;
31
import org.springframework.stereotype.Service;
32
import org.springframework.web.client.RestClientException;
33
import org.springframework.web.client.RestTemplate;
34
import org.springframework.web.util.UriComponentsBuilder;
35

    
36
import javax.annotation.PostConstruct;
37
import java.io.IOException;
38
import java.io.UnsupportedEncodingException;
39
import java.net.URLEncoder;
40
import java.text.Normalizer;
41
import java.util.*;
42
import java.util.concurrent.ConcurrentHashMap;
43
import java.net.URL;
44

    
45
/**
46
 * Created by nikonas on 12/8/15.
47
 */
48
@SuppressWarnings("serial")
49
@Service("repositoryService")
50
public class RepositoryServiceImpl extends SpringGwtRemoteServiceServlet implements RepositoryService {
51

    
52
    private static final Logger LOGGER = Logger
53
            .getLogger(RepositoryServiceImpl.class);
54

    
55
    @Autowired
56
    private RepoApi repoAPI;
57

    
58
    @Autowired
59
    private EmailUtils emailUtils;
60

    
61
    private final String[] vocabularyNames = {"dnet:countries", "dnet:datasource_typologies", "dnet:compatibilityLevel"};
62

    
63
    @Autowired
64
    private VocabularyLoader vocabularyLoader;
65

    
66
    private Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<String, Vocabulary>();
67

    
68
    @Value("${services.repo-manager.repository.testing.mode}")
69
    private boolean testingMode;
70

    
71
    @Autowired
72
    private PiwikDAO piwikDAO;
73

    
74
    @Value("${services.repomanager.analyticsURL}")
75
    private String analyticsURL;
76

    
77
    @Value("${services.repomanager.usageStatisticsDiagramsBaseURL}")
78
    private String usageStatisticsDiagramsBaseURL;
79

    
80
    @Value("${services.repomanager.usageStatisticsNumbersBaseURL}")
81
    private String usageStatisticsNumbersBaseURL;
82

    
83
    private static final String PIWIK_SCRIPT = StringEscapeUtils.escapeHtml("<!-- Piwik -->\n" +
84
            "<script type=\"text/javascript\">\n" +
85
            "\tvar _paq = _paq || [];\n" +
86
            "\t_paq.push(['enableLinkTracking']);\n" +
87
            "\t(function() {\n" +
88
            "\t\tvar u=\"//analytics.openaire.eu/\";\n" +
89
            "\t\t_paq.push(['setTrackerUrl', u+'piwik.php']);\n" +
90
            "\t\t_paq.push(['setSiteId', $$$]);\n" +
91
            "\t\t<% if(handle != null){%>\n" +
92
            "\t\t\t_paq.push(['setCustomVariable', 1, 'oaipmhID',\"oai:<%= baseUrl %>:<%=handle %>\", 'page']);\n" +
93
            "\t\t\t_paq.push(['trackPageView']);\n" +
94
            "\t\t<}>\n" +
95
            "\t\tvar d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];\n" +
96
            "\t\tg.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);\n" +
97
            "\t})();\n" +
98
            "</script>\n" +
99
            "<noscript>\n" +
100
            "\t<p>\n" +
101
            "\t\t<img src=\"//analytics.openaire.eu/piwik.php?idsite=47\" style=\"border:0;\" alt=\"\" />\n" +
102
            "\t</p>\n" +
103
            "</noscript>\n" +
104
            "<!— End Piwik Code —>");
105

    
106

    
107
    @Autowired
108
    private RepositoryApi repositoryApi;
109

    
110

    
111

    
112
    @PostConstruct
113
    public void init() {
114
        this.loadVocabularies();
115
    }
116

    
117
    @Override
118
    public Tuple<List<Repository>, List<Repository>> getRepositoriesByCountry(String country, String mode, boolean includeUnknownCountries) throws RepositoryServiceException {
119
        try {
120
            if (testingMode)
121
                return this.getRepositoriesByCountryTesting(country, mode, includeUnknownCountries);
122
            LOGGER.debug("Getting repositories of country: " + country + " with type: " + mode + " and includeUnknownCountries: " + includeUnknownCountries);
123

    
124
            Tuple<List<Repository>, List<Repository>> retTuple = new Tuple<List<Repository>, List<Repository>>();
125
//            List<Repository> reposList = this.repoAPI.getRepositoriesPerCountry(mode).get(country);
126

    
127
            List<Repository> reposList = repositoryApi.getRepositoriesByCountry(country,mode);
128
            if (reposList == null) {
129
                retTuple.setFirst(new ArrayList<Repository>());
130
//                if (!includeUnknownCountries) {
131
//                    throw new RepositoryServiceException("registration.noReposForThisCountry", RepositoryServiceException.ErrorCode.NO_REPOS_FOR_THIS_COUNTRY);
132
//                }
133
            } else {
134
                retTuple.setFirst(reposList);
135
            }
136

    
137
            if (includeUnknownCountries) {
138
                List<Repository> withoutCountryList = this.repoAPI.getRepositoriesPerCountry(mode).get("Without Country");
139
                List<Repository> unknownCountryList = this.repoAPI.getRepositoriesPerCountry(mode).get("UNKNOWN");
140
                List<Repository> totalList = new ArrayList<Repository>();
141
                if (withoutCountryList != null)
142
                    totalList.addAll(withoutCountryList);
143
                if (unknownCountryList != null)
144
                    totalList.addAll(unknownCountryList);
145
                retTuple.setSecond(totalList);
146
            }
147

    
148
            return retTuple;
149

    
150
        } catch (Exception e) {
151
            LOGGER.error("Error while getting repositories of country: " + country + " with type: " + mode + " and includeUnknownCountries: " + includeUnknownCountries, e);
152
            if (e instanceof RepositoryServiceException) {
153
                throw (RepositoryServiceException) e;
154
            } else {
155
                emailUtils.reportException(e);
156
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
157
            }
158
        }
159
    }
160

    
161
    @Override
162
    public List<Repository> getRepositoriesByCountry(String country, String mode) throws RepositoryServiceException {
163
        return this.getRepositoriesByCountry(country, mode, false).getFirst();
164
    }
165

    
166
    @Override
167
    public DatasourcesCollection getRepositoriesOfUser(String userEmail, boolean includeShared, boolean includeByOthers) throws RepositoryServiceException {
168

    
169
        DatasourcesCollection retDatasources = new DatasourcesCollection();
170
        try {
171
            LOGGER.debug("Getting repositories of user: " + userEmail + " . IncludeShared: "
172
                    + includeShared + " . IncludeByOthers: " + includeByOthers);
173
            int page = 1;
174
            String size = "10";
175
            List<Repository> resultSet = repositoryApi.getRepositoriesOfUser(userEmail,String.valueOf(page),size);
176
            while(resultSet.size() > 0 ){
177
                retDatasources.getDatasourcesOfUser().addAll(resultSet);
178
                page++;
179
                resultSet = repositoryApi.getRepositoriesOfUser(userEmail,String.valueOf(page),size);
180
            }
181

    
182
/*
183
	if (includeShared) {
184
                //TODO create dao to save-get shared datasourcesIDs
185
                List<String> sharedDatasourceIds = new ArrayList<String>();
186
                retDatasources.setSharedDatasources(this.repoAPI.getReposByIds(sharedDatasourceIds));
187
                //geting Piwik Info
188
                for(Repository repository: retDatasources.getSharedDatasources())
189
                    repository.setPiwikInfo(this.getPiwikSiteForRepository(repository.getId()));
190
            }
191

    
192
            if (includeByOthers) {
193
                retDatasources.setDatasourcesOfOthers(this.repoAPI.getRepositoriesOfUser(userEmail, true));
194
                //geting Piwik Info
195
                for(Repository repository: retDatasources.getDatasourcesOfOthers())
196
                    repository.setPiwikInfo(this.getPiwikSiteForRepository(repository.getId()));
197
            }
198
*/
199
        } catch (JSONException e) {
200
            LOGGER.error("Error while getting repositories of user: " + userEmail + " . IncludeShared: " + includeShared + " . IncludeByOthers: " + includeByOthers, e);
201
            emailUtils.reportException(e);
202
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
203
        }
204
        return retDatasources;
205
    }
206

    
207
    @Override
208
    public List<String> getRepositoryUrlsOfUser(String userEmail, boolean includeShared, boolean includeByOthers) throws RepositoryServiceException {
209
        try {
210
            LOGGER.debug("Getting repositories(urls) of user: " + userEmail + " . IncludeShared: " + includeShared + " . IncludeByOthers: " + includeByOthers);
211
            List<String> retRepos = new ArrayList<String>();
212

    
213
            int page = 1;
214
            String size = "10";
215
            List<String> resultSet = repositoryApi.getUrlsOfUserRepos(userEmail,String.valueOf(page),size);
216
            while(resultSet.size() > 0 ){
217
                retRepos.addAll(resultSet);
218
                page++;
219
                resultSet = repositoryApi.getUrlsOfUserRepos(userEmail,String.valueOf(page),size);
220
            }
221
            return retRepos;
222

    
223
        } catch (Exception e) {
224
            LOGGER.error("Error while getting repositories(urls) of user: " + userEmail + " . IncludeShared: " + includeShared + " . IncludeByOthers: " + includeByOthers, e);
225
            emailUtils.reportException(e);
226
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
227
        }
228
    }
229

    
230
    @Override
231
    public Repository getRepository(String repoId) throws RepositoryServiceException {
232
        try {
233
            LOGGER.debug("Getting repository with id: " + repoId);
234
            Repository repo = repositoryApi.getRepositoryById(repoId);
235

    
236
            if (repo != null) {
237
                for (RepositoryInterface iFace : repo.getInterfaces()) {
238
                    if (!iFace.getContentDescription().equals("file::hybrid") && iFace.getAccessProtocol().equalsIgnoreCase("oai")) {
239
                        iFace.setComplianceName(getComplianceName(iFace.getCompliance()));
240
                        if (iFace.getCompliance().equals("notCompatible"))
241
                            iFace.setComplianceName("not compatible");
242
                    }
243
                }
244

    
245
                //geting Piwik Info
246
                repo.setPiwikInfo(this.getPiwikSiteForRepository(repoId));
247

    
248
            } else
249
                throw new RepositoryServiceException("registration.repositoryNotExists", RepositoryServiceException.ErrorCode.REPOSITORY_NOT_EXISTS);
250
            return repo;
251

    
252
        } catch (Exception e) {
253
            LOGGER.error("Error while getting repository with id: " + repoId, e);
254
            if (e instanceof RepositoryServiceException) {
255
                throw (RepositoryServiceException) e;
256
            } else {
257
                emailUtils.reportException(e);
258
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
259
            }
260
        }
261
    }
262

    
263
    @Override
264
    public Map<String, String> getCountries(Boolean existingOnly, String mode) throws RepositoryServiceException {
265
        try {
266
            LOGGER.debug("Getting countries");
267
            List<String> countries = new ArrayList<String>();
268

    
269
            Map<String, String> countriesMap = new TreeMap<String, String>();
270

    
271
            if (existingOnly) {
272
                LOGGER.debug("using the repositories map");
273
                countries.addAll(this.repoAPI.getRepositoriesByCountry(mode).keySet());
274
            } else {
275
                LOGGER.debug("using \"dnet:countries\" vocabulary");
276
                countries.addAll(this.getVocabulary("dnet:countries").getEnglishNames());
277
            }
278
//            countries.addAll(repositoryApi.getDnetCountries());
279
            for (String country : countries) {
280
                countriesMap.put(country, WordUtils.capitalizeFully(country));
281
            }
282

    
283
            return countriesMap;
284

    
285
        } catch (Exception e) {
286
            LOGGER.error("Error while getting getting countries", e);
287
            if (e instanceof RepositoryServiceException) {
288
                throw (RepositoryServiceException) e;
289
            } else {
290
                emailUtils.reportException(e);
291
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
292
            }
293
        }
294
    }
295

    
296
    @Override
297
    public Map<String, String> getCountries() throws RepositoryServiceException {
298
        return this.getCountries(false, null);
299
    }
300

    
301
    @Override
302
    public List<Timezone> getTimezones() throws RepositoryServiceException {
303
        try {
304
            LOGGER.debug("Getting timezones from file");
305
//            return repositoryApi.getTimezones();
306
            return LocalVocabularies.timezones;
307
        } catch (Exception e) {
308
            LOGGER.error("Error while getting timezones from file", e);
309
            emailUtils.reportException(e);
310
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
311
        }
312

    
313
    }
314

    
315
    @Override
316
    public List<String> getTypologies() throws RepositoryServiceException {
317
        try {
318
            LOGGER.debug("Getting typologies from file");
319
           // return repositoryApi.getTypologies();
320
            return LocalVocabularies.typologies;
321
        } catch (Exception e) {
322
            LOGGER.error("Error while getting typologies from file", e);
323
            emailUtils.reportException(e);
324
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
325
        }
326
    }
327

    
328
    @Override
329
    public Map<String, String> getDatasourceClasses(String mode) throws RepositoryServiceException {
330
        return repositoryApi.getDatasourceClasses(mode);
331
    }
332

    
333
    @Override
334
    public Map<String, String> getCompatibilityClasses(String mode) throws RepositoryServiceException {
335
        return repositoryApi.getCompatibilityClasses(mode);
336
    }
337

    
338
    @Override
339
    public void storeRepository(Repository repo, String mode) throws RepositoryServiceException {
340

    
341
        try {
342
            LOGGER.debug("Storing repository with name: " + repo.getOfficialName());
343
            List<RepositoryInterface> interfacesToRegister = new ArrayList<RepositoryInterface>();
344

    
345
            //TODO update map
346
            repo.setCountryCode(getCountryCode(repo.getCountryName()));
347

    
348
            repo.setActivationId(UUID.randomUUID().toString());
349
//            repo.setRegisteredBy((String) session.get(LocalVocabularies.loggedInField));
350

    
351
            if (mode.equals("opendoar") || mode.equals("re3data")) {
352
                repo.setProvenanceActionClass("sysimport:crosswalk:entityregistry");
353
            } else if (mode.equals("journal")) {
354
                repo.setProvenanceActionClass("user:insert");
355
                repo.setCollectedFrom("infrastruct_::openaire");
356
                if (repo.getIssn() != null && repo.getIssn().length() == 0)
357
                    repo.setIssn(Base64.encode(repo.getOfficialName()).substring(0, 8));
358
                repo.setId("openaire____::issn" + repo.getIssn());
359
                repo.setNamespacePrefix("issn" + repo.getIssn());
360
            } else if (mode.equals("aggregator")) {
361
                repo.setProvenanceActionClass("user:insert");
362
                repo.setCollectedFrom("infrastruct_::openaire");
363
                repo.setId("openaire____::" + Base64.encode(repo.getOfficialName()));
364
                repo.setNamespacePrefix(Normalizer.normalize(repo.getOfficialName().toLowerCase().replace(" ", "_"), Normalizer.Form.NFD).replaceAll("[^a-zA-Z0-9]", ""));
365
                if (repo.getNamespacePrefix().length() > 12) {
366
                    repo.setNamespacePrefix(repo.getNamespacePrefix().substring(0, 12));
367
                } else {
368
                    while (repo.getNamespacePrefix().length() < 12)
369
                        repo.setNamespacePrefix(repo.getNamespacePrefix().concat("_"));
370
                }
371
            }
372
            repositoryApi.addRepository(repo);
373
        } catch (JSONException e) {
374
            LOGGER.error("Error while Storing repository with name: " + repo.getOfficialName(), e);
375
	    emailUtils.reportException(e);
376
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
377
        }
378
    }
379

    
380
    @Override
381
    public void updateRepositoryInformation(Repository repo) throws RepositoryServiceException {
382
        try {
383
            LOGGER.debug("Updating information of repo: " + repo.getOfficialName());
384

    
385
	    //TODO SOS, check old API
386

    
387
            //this.repoAPI.updateRepositoryInformation(repo);
388
            repositoryApi.updateEnglishName(repo.getId(),repo.getEnglishName());
389
            repositoryApi.updateLatitude(repo.getId(), String.valueOf(repo.getLatitude()));
390
            repositoryApi.updateLongitude(repo.getId(), String.valueOf(repo.getLongitude()));
391
            repositoryApi.updateOfficialName(repo.getId(),repo.getOfficialName());
392
        } catch (Exception e) {
393
            LOGGER.error("Error while updating information of repo: " + repo.getOfficialName(), e);
394
            if (e instanceof RepositoryServiceException) {
395
                throw (RepositoryServiceException) e;
396
            } else {
397
                emailUtils.reportException(e);
398
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
399
            }
400
        }
401
    }
402

    
403
    @Override
404
    public RepositoryInterface updateInterface(RepositoryInterface iFace, String repoId, String datatype) throws RepositoryServiceException {
405
        try {
406
            LOGGER.debug("updating interface with id: " + iFace.getId());
407
            RepositoryInterface retIface = null;
408
            retIface = this.repoAPI.updateRepositoryInterfaceWithoutChecks(repoId, iFace, datatype);
409
            retIface.setComplianceName(this.getComplianceName(retIface.getCompliance()));
410

    
411
            return retIface;
412
        } catch (Exception e) {
413
            LOGGER.error("error updating interface with id: " + iFace.getId(), e);
414
            if (e instanceof RepositoryServiceException) {
415
                throw (RepositoryServiceException) e;
416
            } else {
417
                emailUtils.reportException(e);
418
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
419
            }
420
        }
421
    }
422

    
423
    @Override
424
    public RepositoryInterface insertInterface(RepositoryInterface iFace, String repoId, String datatype) throws RepositoryServiceException {
425
        try {
426
            LOGGER.debug("inserting interface with id: " + iFace.getId());
427
            RepositoryInterface retIface = null;
428
            //retIface = this.repoAPI.insertRepositoryInterfaceWithoutChecks(repoId, iFace, datatype);
429

    
430
            Repository e = this.getRepository(repoId);
431
            iFace.setContentDescription("metadata");
432
            iFace.setCompliance("UNKNOWN");
433
            if(e.getDatasourceClass() == null) {
434
                if(datatype.equalsIgnoreCase("journal")) {
435
                    iFace.setTypology("pubsrepository::journal");
436
                } else if(datatype.equalsIgnoreCase("aggregator")) {
437
                    iFace.setTypology("aggregator::pubsrepository::unknown");
438
                } else {
439
                    iFace.setTypology("pubsrepository::unknown");
440
                }
441
            } else {
442
                iFace.setTypology(e.getDatasourceClass());
443
            }
444

    
445
            if(datatype.equals("re3data")) {
446
                iFace.setAccessFormat("oai_datacite");
447
            } else {
448
                iFace.setAccessFormat("oai_dc");
449
            }
450

    
451
            iFace.setAccessProtocol("oai");
452
            iFace.setRemovable(true);
453
            iFace.setMetadataIdentifierPath("//*[local-name()=\'header\']/*[local-name()=\'identifier\']");
454
            iFace.setId("api_________::" + repoId + "::" + UUID.randomUUID().toString().substring(0, 8));
455
            if(iFace.getAccessSet().isEmpty()) {
456
                LOGGER.debug("set is empty: " + iFace.getAccessSet());
457
                iFace.removeAccessSet();
458
            }
459

    
460
            retIface = repositoryApi.addRepositoryInterface(iFace);
461
            retIface.setComplianceName(this.getComplianceName(retIface.getCompliance()));
462

    
463
            return retIface;
464

    
465
        } catch (Exception e) {
466
            LOGGER.error("error updating interface with id: " + iFace.getId(), e);
467
            if (e instanceof RepositoryServiceException) {
468
                throw (RepositoryServiceException) e;
469
            } else {
470
                emailUtils.reportException(e);
471
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
472
            }
473
        }
474
    }
475

    
476
    @Override
477
    public void deleteInterface(String repoId, RepositoryInterface iFace, String datatype) throws RepositoryServiceException {
478
        List<RepositoryInterface> iFaces = new ArrayList<RepositoryInterface>();
479
        iFaces.add(iFace);
480
        this.deleteInterfaces(repoId, iFaces, datatype);
481
    }
482

    
483
    @Override
484
    public void deleteInterfaces(String repoId, List<RepositoryInterface> iFaces, String datatype) throws RepositoryServiceException {
485
        try {
486
            LOGGER.debug("deleting interfaces of repo: " + repoId);
487
            //this.repoAPI.deleteRepositoryInterfacesWithoutChecks(repoId, iFaces, datatype);
488

    
489
            for(RepositoryInterface iFace : iFaces) {
490
                LOGGER.info("deleting repository interface with url/set/id: " + iFace.getBaseUrl() + "/"
491
                        + iFace.getAccessSet() + "/" + iFace.getId());
492
                repositoryApi.deleteRepositoryInterface(iFace.getId());
493
            }
494

    
495
        } catch (Exception e) {
496
            LOGGER.error("deleting interfaces of repo: " + repoId, e);
497
            if (e instanceof RepositoryServiceException) {
498
                throw (RepositoryServiceException) e;
499
            } else {
500
                emailUtils.reportException(e);
501
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
502
            }
503
        }
504

    
505
    }
506

    
507
    @Override
508
    public DatasourceVocabularies getDatasourceVocabularies(String mode) throws RepositoryServiceException {
509
        try {
510
            LOGGER.debug("Getting vocabularies for datasource with type: " + mode);
511
            DatasourceVocabularies vocs = new DatasourceVocabularies();
512
            vocs.setCountries(this.getCountries());
513
            vocs.setDatasourceClasses(this.getDatasourceClasses(mode));
514
            vocs.setTimezones(this.getTimezones());
515
            vocs.setTypologies(this.getTypologies());
516
            vocs.setCompatibilityLevels(this.getCompatibilityClasses(mode));
517

    
518
            return vocs;
519

    
520
        } catch (Exception e) {
521
            LOGGER.error("Error while getting vocabularies for datasource with type: \" + mode", e);
522
            emailUtils.reportException(e);
523
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
524
        }
525
    }
526

    
527
    private Tuple<List<Repository>, List<Repository>> getRepositoriesByCountryTesting(String country, String mode, boolean includeUnknownCountries) throws RepositoryServiceException {
528
        try {
529
            LOGGER.debug("Getting testing repositories of country: " + country + " with type: " + mode + " and includeUnknownCountries: " + includeUnknownCountries);
530

    
531
            Tuple<List<Repository>, List<Repository>> retTuple = new Tuple<List<Repository>, List<Repository>>();
532
            List<Repository> reposList = new ArrayList<Repository>();
533
            reposList.add(this.repoAPI.getRepository("opendoar____::1356"));
534
            reposList.add(this.repoAPI.getRepository("opendoar____::2678"));
535
            reposList.add(this.repoAPI.getRepository("opendoar____::2980"));
536
            reposList.add(this.repoAPI.getRepository("opendoar____::1347"));
537
            reposList.add(this.repoAPI.getRepository("opendoar____::2984"));
538

    
539
            retTuple.setFirst(reposList);
540

    
541
            if (includeUnknownCountries) {
542
                List<Repository> totalList = new ArrayList<Repository>();
543
                totalList.add(this.repoAPI.getRepository("opendoar____::3000"));
544
                totalList.add(this.repoAPI.getRepository("opendoar____::1027"));
545
                totalList.add(this.repoAPI.getRepository("opendoar____::1096"));
546

    
547
                retTuple.setSecond(totalList);
548
            }
549

    
550
            return retTuple;
551

    
552
        } catch (Exception e) {
553
            LOGGER.error("Error while getting testing repositories of country: " + country + " with type: " + mode + " and includeUnknownCountries: " + includeUnknownCountries, e);
554
            if (e instanceof RepositoryServiceException) {
555
                throw (RepositoryServiceException) e;
556
            } else {
557
                emailUtils.reportException(e);
558
                throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
559
            }
560
        }
561
    }
562

    
563
    @Override
564
    public String getLatestUpdateDateOfList(String mode) throws RepositoryServiceException {
565
        try {
566
            LOGGER.debug("Getting latest update date of list: " + mode);
567
            return this.repoAPI.getListLatestUpdate(mode).split("T")[0];
568

    
569
        } catch (Exception e) {
570
            LOGGER.error("Error while getting latest update date of list: " + mode, e);
571
            emailUtils.reportException(e);
572
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
573
        }
574
    }
575

    
576
    @Override
577
    public PiwikInfo getPiwikSiteForRepository(String repoId) throws RepositoryServiceException {
578
        try {
579
            LOGGER.debug("Repo id -> " + repoId);
580
            return this.piwikDAO.getPiwikSiteForRepo(repoId);
581
        } catch (EmptyResultDataAccessException e) {
582
            return null;
583
        }
584
    }
585

    
586
    @Override
587
    public void enableMetricsForRepository(Repository repository, UserProfile requestor) throws RepositoryServiceException {
588
        
589
        try {
590
            String URL = analyticsURL + "siteName=" + URLEncoder.encode(repository.getOfficialName(), "UTF-8") + "&url=" + URLEncoder.encode(repository.getWebsiteUrl(), "UTF-8");
591
            Map<String, Object> map = new ObjectMapper().readValue(new URL(URL), Map.class);
592

    
593
            String siteId = null;
594
            if(map.get("value")!=null) {
595
                siteId = map.get("value").toString();
596
            }
597

    
598
            String authenticationToken = "32846584f571be9b57488bf4088f30ea";
599

    
600
            PiwikInfo piwikInfo = new PiwikInfo();
601
            piwikInfo.setRepositoryId(repository.getId());
602
            piwikInfo.setRepositoryName(repository.getOfficialName());
603
            piwikInfo.setCountry(repository.getCountryName());
604
            piwikInfo.setSiteId(siteId);
605
            piwikInfo.setAuthenticationToken(authenticationToken);
606
            piwikInfo.setRequestorEmail(requestor.getEmail());
607
            piwikInfo.setRequestorName(requestor.getFirstname() + " " + requestor.getLastname());
608
            piwikInfo.setValidated(false);
609

    
610
            this.piwikDAO.savePiwikInfo(piwikInfo);
611

    
612
            emailUtils.sendAdministratorRequestToEnableMetrics(piwikInfo);
613
            emailUtils.sendUserRequestToEnableMetrics(piwikInfo);
614

    
615
        } catch (UnsupportedEncodingException uee) {
616
            LOGGER.error("Error while creating piwikScript URL", uee);
617
            emailUtils.reportException(uee);
618
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
619
        } catch (IOException ioe) {
620
            LOGGER.error("Error while creating piwik site", ioe);
621
            emailUtils.reportException(ioe);
622
            throw new RepositoryServiceException("login.generalError", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
623
        } catch (Exception e) {
624
            LOGGER.error("Error while sending email to administrator or user about the request to enable metrics", e);
625
            emailUtils.reportException(e);
626
        }
627
    }
628

    
629
    @Override
630
    public String getPiwikScriptForRepository(String repoId) throws RepositoryServiceException {
631
        try {
632
            PiwikInfo piwikInfo = this.piwikDAO.getPiwikSiteForRepo(repoId);
633

    
634
            String piwikScript = PIWIK_SCRIPT.replace("$$$", piwikInfo.getSiteId());
635
            return piwikScript;
636

    
637
        } catch (EmptyResultDataAccessException e) {
638
            return null;
639
        }
640
    }
641

    
642
    @Override
643
    public List<PiwikInfo> getPiwikSitesForRepositories() throws RepositoryServiceException {
644
        try {
645

    
646
            List<PiwikInfo> piwikInfos = new ArrayList<>();
647
            piwikInfos = this.piwikDAO.getPiwikSitesForRepos();
648

    
649
            return piwikInfos;
650

    
651
        } catch (EmptyResultDataAccessException e) {
652
            LOGGER.error("Error while getting list of piwik sites: ", e);
653
            emailUtils.reportException(e);
654
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
655
        }
656
    }
657

    
658
    @Override
659
    public void markPiwikSiteAsValidated(String repositoryId) throws RepositoryServiceException {
660
        try {
661
            this.piwikDAO.markPiwikSiteAsValidated(repositoryId);
662

    
663
            PiwikInfo piwikInfo = this.piwikDAO.getPiwikSiteForRepo(repositoryId);
664
            emailUtils.sendAdministratorMetricsEnabled(piwikInfo);
665
            emailUtils.sendUserMetricsEnabled(piwikInfo);
666

    
667
        } catch (EmptyResultDataAccessException e) {
668
            LOGGER.error("Error while approving piwik site: ", e);
669
            emailUtils.reportException(e);
670
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
671
        } catch (Exception e) {
672
            LOGGER.error("Error while sending email to administrator or user about the enabling of metrics", e);
673
            emailUtils.reportException(e);
674
        }
675
    }
676

    
677
    @Override
678
    public MetricsInfo getMetricsInfoForRepository(String repoId) throws RepositoryServiceException {
679
        try {
680

    
681
            MetricsInfo metricsInfo = new MetricsInfo();
682
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
683
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
684
            return metricsInfo;
685

    
686
        } catch (Exception e) {
687
            LOGGER.error("Error while getting metrics info for repository: ", e);
688
            emailUtils.reportException(e);
689
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
690
        }
691
    }
692

    
693
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
694

    
695
        //build the uri params
696
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
697

    
698
        //create new template engine
699
        RestTemplate template = new RestTemplate();
700
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
701
        ResponseEntity<MetricsNumbers> resp;
702
        try {
703
            //communicate with endpoint
704
            resp = template.exchange(
705
                    builder.build().encode().toUri(),
706
                    HttpMethod.GET,
707
                    null,
708
                    new ParameterizedTypeReference<MetricsNumbers>() {
709
                    });
710
        } catch (RestClientException e) {
711
            throw e;
712
        }
713

    
714
        return resp.getBody();
715
    }
716

    
717
    private String getCountryCode(String countryName) {
718
        Vocabulary countries = this.getVocabulary("dnet:countries");
719

    
720
        return countries.getEncoding(countryName);
721
    }
722

    
723
    private String getDatasourceClassCode(String datasourceClassName) {
724
        Vocabulary datasourceClasses = this.getVocabulary("dnet:datasource_typologies");
725

    
726
        return datasourceClasses.getEncoding(datasourceClassName);
727
    }
728

    
729
    private String getComplianceName(String complianceCode) {
730
        Vocabulary compatibilityLevels = this.getVocabulary("dnet:compatibilityLevel");
731

    
732
        return compatibilityLevels.getEnglishName(complianceCode);
733
    }
734

    
735
    private Vocabulary getVocabulary(String vocName) {
736

    
737
        if (!vocabularyMap.containsKey(vocName)) {
738
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
739
        }
740
        return vocabularyMap.get(vocName);
741
    }
742

    
743
    @Scheduled(fixedRate = 3600000)
744
    private void loadVocabularies() {
745
        LOGGER.debug("loading vocabularies");
746
        for (String vocName : vocabularyNames) {
747
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
748
        }
749
    }
750

    
751
    private String getOpenAIREId(String repoId) {
752

    
753
        if (repoId != null && repoId.contains("::")) {
754
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
755
        }
756

    
757
        return null;
758
    }
759
}
(4-4/6)