Project

General

Profile

1
package eu.dnetlib.repo.manager.service;
2

    
3
import com.fasterxml.jackson.core.JsonProcessingException;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import com.fasterxml.jackson.databind.SerializationFeature;
6
import eu.dnetlib.api.functionality.ValidatorServiceException;
7
import eu.dnetlib.domain.data.Repository;
8
import eu.dnetlib.domain.data.RepositoryInterface;
9
import eu.dnetlib.domain.enabling.Vocabulary;
10
import eu.dnetlib.domain.functionality.validator.JobForValidation;
11
import eu.dnetlib.repo.manager.domain.RepositorySnippet;
12
import eu.dnetlib.repo.manager.domain.RequestFilter;
13
import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
14
import eu.dnetlib.repo.manager.shared.*;
15
import eu.dnetlib.repo.manager.utils.Converter;
16
import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
17
import gr.uoa.di.driver.xml.repository.INTERFACE;
18
import org.apache.commons.codec.digest.DigestUtils;
19
import org.apache.log4j.Logger;
20
import org.json.JSONArray;
21
import org.json.JSONException;
22
import org.json.JSONObject;
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.http.*;
27
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
28
import org.springframework.security.core.Authentication;
29
import org.springframework.security.core.context.SecurityContextHolder;
30
import org.springframework.stereotype.Service;
31
import org.springframework.web.bind.annotation.PathVariable;
32
import org.springframework.web.bind.annotation.RequestBody;
33
import org.springframework.web.bind.annotation.RequestParam;
34
import org.springframework.web.client.RestClientException;
35
import org.springframework.web.client.RestTemplate;
36
import org.springframework.web.util.UriComponents;
37
import org.springframework.web.util.UriComponentsBuilder;
38

    
39
import javax.annotation.PostConstruct;
40
import java.io.IOException;
41
import java.sql.Timestamp;
42
import java.util.*;
43
import java.util.concurrent.ConcurrentHashMap;
44
import java.util.stream.Collectors;
45

    
46
@Service("repositoryService")
47
public class RepositoryServiceImpl implements RepositoryService {
48

    
49
    @Value("${api.baseAddress}")
50
    private String baseAddress;
51

    
52
    @Value("${services.repo-manager.adminEmail}")
53
    private String adminEmail;
54

    
55
    @Autowired
56
    RestTemplate restTemplate;
57

    
58
    private HttpHeaders httpHeaders;
59

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

    
62
    private static final Logger LOGGER = Logger.getLogger(RepositoryServiceImpl.class);
63

    
64
    @Value("${services.repomanager.usageStatisticsDiagramsBaseURL}")
65
    private String usageStatisticsDiagramsBaseURL;
66

    
67
    @Value("${services.repomanager.usageStatisticsNumbersBaseURL}")
68
    private String usageStatisticsNumbersBaseURL;
69

    
70
    @Autowired
71
    private VocabularyLoader vocabularyLoader;
72

    
73
    @Autowired
74
    private PiWikService piWikService;
75

    
76
    @Autowired
77
    private EmailUtils emailUtils;
78

    
79
    @Autowired
80
    ValidatorService validatorService;
81

    
82

    
83
    private Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<>();
84

    
85
    private Map<String, String> countriesMap = new HashMap<>();
86
    private Map<String, String> inverseCountriesMap = new HashMap<>();
87

    
88
    private static Map<String,List<String>> dataSourceClass = new HashMap<>();
89

    
90
    private static Map<String,String> invertedDataSourceClass = new HashMap<>();
91

    
92

    
93

    
94
    @PostConstruct
95
    private void init() {
96
        LOGGER.debug("Initialization method of repository api!");
97
        LOGGER.debug("Updated version!");
98

    
99
        dataSourceClass.put("opendoar",Arrays.asList("pubsrepository::institutional","pubsrepository::thematic","pubsrepository::unknown","pubsrepository::mock"));
100
        dataSourceClass.put("re3data", Collections.singletonList("datarepository::unknown"));
101
        dataSourceClass.put("journal", Collections.singletonList("pubsrepository::journal"));
102
        dataSourceClass.put("aggregator",Arrays.asList("aggregator::pubsrepository::institutional","aggregator::pubsrepository::journals","aggregator::datarepository", "aggregator::pubsrepository::unknown"));
103

    
104
        invertedDataSourceClass.put("pubsrepository::institutional","opendoar");
105
        invertedDataSourceClass.put("pubsrepository::thematic","opendoar");
106
        invertedDataSourceClass.put("pubsrepository::unknown","opendoar");
107
        invertedDataSourceClass.put("pubsrepository::mock","opendoar");
108
        invertedDataSourceClass.put("datarepository::unknown","re3data");
109
        invertedDataSourceClass.put("pubsrepository::journal","journal");
110
        invertedDataSourceClass.put("aggregator::pubsrepository::institutional","aggregator");
111
        invertedDataSourceClass.put("aggregator::pubsrepository::journals","aggregator");
112
        invertedDataSourceClass.put("aggregator::datarepository","aggregator");
113
        invertedDataSourceClass.put("aggregator::pubsrepository::unknown","aggregator");
114

    
115

    
116
        httpHeaders = new HttpHeaders();
117
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
118

    
119
        for (String vocName : vocabularyNames) {
120
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
121
        }
122

    
123
        Country[] countries = getCountries();
124
        for (Country c : countries) {
125
            countriesMap.put(c.getName(), c.getCode());
126
            inverseCountriesMap.put(c.getCode(), c.getName());
127
        }
128

    
129

    
130
    }
131

    
132
    @Override
133
    public Country[] getCountries() {
134
        UriComponents uriComponents = UriComponentsBuilder
135
                .fromHttpUrl(baseAddress + "/ds/countries")
136
                .build().encode();
137
        return restTemplate.getForObject(uriComponents.toUri(), Country[].class);
138
    }
139

    
140

    
141
    @Override
142
    public List<RepositorySnippet> getRepositoriesByCountry(String country,
143
                                                            String mode,
144
                                                            Boolean managed) throws JSONException, IOException {
145

    
146
        LOGGER.debug("Getting repositories by country!");
147
        int page = 0;
148
        int size = 100;
149
        List<RepositorySnippet> resultSet = new ArrayList<>();
150
        ObjectMapper mapper = new ObjectMapper();
151

    
152
        String filterKey = "UNKNOWN";
153
        if (mode.equalsIgnoreCase("opendoar"))
154
            filterKey = "openaire____::opendoar";
155
        else if (mode.equalsIgnoreCase("re3data"))
156
            filterKey = "openaire____::re3data";
157

    
158

    
159
        LOGGER.debug("Country code equals : " + country);
160
        LOGGER.debug("Filter mode equals : " + filterKey);
161

    
162
        UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size));
163
        RequestFilter requestFilter = new RequestFilter();
164
        requestFilter.setCountry(country);
165
        requestFilter.setCollectedfrom(filterKey);
166

    
167
        try{
168
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
169
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
170
            while (jsonArray.length() > 0 ) {
171
                resultSet.addAll(mapper.readValue(String.valueOf(jsonArray),
172
                        mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class)));
173
                page += 1;
174
                uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size));
175
                rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
176
                jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
177
            }
178
            return resultSet;
179
        }catch (Exception e){
180
            LOGGER.debug("Exception on getRepositoriesByCountry" , e);
181
//            emailUtils.reportException(e);
182
            throw e;
183
        }
184
    }
185

    
186
    public List<RepositorySnippet> searchRegisteredRepositories(String country, String typology, String englishName,
187
            String officialName, String requestSortBy, String order, int page, int pageSize) throws Exception {
188

    
189
        LOGGER.debug("Searching registered repositories");
190

    
191
        List<RepositorySnippet> resultSet = new ArrayList<>();
192
        ObjectMapper mapper = new ObjectMapper();
193

    
194
        UriComponents uriComponents = searchRegisteredDatasource(requestSortBy, order, Integer.toString(page), Integer.toString(pageSize));
195

    
196
        RequestFilter requestFilter = new RequestFilter();
197
        requestFilter.setCountry(country);
198
        requestFilter.setTypology(typology);
199
        requestFilter.setOfficialname(officialName);
200
        requestFilter.setEnglishname(englishName);
201

    
202
        try {
203
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
204
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
205

    
206
            resultSet.addAll(mapper.readValue(String.valueOf(jsonArray),  mapper.getTypeFactory().constructCollectionType(List.class, RepositorySnippet.class)));
207

    
208
             return resultSet;
209
        }catch (Exception e){
210
            LOGGER.error("Error searching registered datasources" , e);
211
            throw e;
212
        }
213
    }
214

    
215
    private Repository updateRepositoryInfo(Repository r) throws JSONException {
216

    
217
        /*
218
        * from datasource class
219
        * we get the datasource type form the inverted map
220
        * */
221
        r.setDatasourceType(getRepositoryType(r.getDatasourceClass()));
222
        r.setInterfaces(this.getRepositoryInterface(r.getId()));
223
        r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId()));
224
        r.setCountryName(getCountryName(r.getCountryCode()));
225
        return r;
226
    }
227

    
228

    
229
    private Collection<Repository> getRepositoriesByMode(String mode, List<Repository> rs) {
230

    
231
        List<Repository> reps = new ArrayList<>();
232
        for (Repository r : rs) {
233
            if (r.getCollectedFrom() != null && r.getCollectedFrom().equals(mode))
234
                reps.add(r);
235

    
236
        }
237
        return reps;
238
    }
239

    
240
    @Override
241
    public List<Repository> getRepositoriesOfUser(String userEmail,
242
                                                  String page,
243
                                                  String size) throws JSONException {
244

    
245
        LOGGER.debug("Retreiving repositories of user : " + userEmail );
246
        UriComponents uriComponents = searchDatasource(page,size);
247
        RequestFilter requestFilter = new RequestFilter();
248
        requestFilter.setRegisteredby(userEmail);
249

    
250
        try{
251
            long start = System.currentTimeMillis();
252
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
253
            long end = System.currentTimeMillis();
254

    
255
            System.out.println("POST request finished in " + (end-start)+"ms");
256
            start=System.currentTimeMillis();
257
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
258
            end=System.currentTimeMillis();
259
            System.out.println("Converting json to repo list finished in " + (end-start)+"ms");
260
            start=System.currentTimeMillis();
261
            for (Repository r : repos)
262
                this.updateRepositoryInfo(r);
263
            end=System.currentTimeMillis();
264
            System.out.println("Updating "+repos.size()+" repository infos in " + (end-start)+"ms");
265
            return repos;
266
        }catch (Exception e){
267
            LOGGER.debug("Exception on getRepositoriesOfUser" , e);
268
            emailUtils.reportException(e);
269
            throw e;
270
        }
271
    }
272

    
273
    @Override
274
    public Repository getRepositoryById(String id) throws JSONException,ResourceNotFoundException {
275

    
276
        LOGGER.debug("Retreiving repositories with id : " + id );
277
        Repository repo = null;
278
        UriComponents uriComponents = searchDatasource("0","100");
279
        RequestFilter requestFilter = new RequestFilter();
280
        requestFilter.setId(id);
281

    
282
        try{
283
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
284
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
285

    
286
            if(jsonArray.length() == 0)
287
                throw new ResourceNotFoundException();
288

    
289
            repo = Converter.jsonToRepositoryObject(jsonArray.getJSONObject(0));
290
            return updateRepositoryInfo(repo);
291
        }catch (JSONException e){
292
            LOGGER.debug("Exception on getRepositoryById" , e);
293
            emailUtils.reportException(e);
294
            throw e;
295
        }
296

    
297
    }
298

    
299

    
300
    @Override
301
    public List<AggregationDetails> getRepositoryAggregations(String id, int from, int size) throws JSONException {
302

    
303
        LOGGER.debug("Retreiving aggregations for repository with id : " + id );
304
        UriComponents uriComponents = searchDatasource(from+"",size+"");
305
        RequestFilter requestFilter = new RequestFilter();
306
        requestFilter.setId(id);
307

    
308
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
309

    
310
        try {
311
            long start = System.currentTimeMillis();
312
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
313
            long end = System.currentTimeMillis();
314

    
315
            System.out.println("Aggregations request through rest template took " + (end-start)+"ms");
316
            JSONObject repository = new JSONObject(rs);
317

    
318
            if(repository.getJSONArray("datasourceInfo").length() == 0)
319
                return aggregationHistory;
320

    
321
            start = System.currentTimeMillis();
322
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
323
            end = System.currentTimeMillis();
324

    
325
            System.out.println("Getting aggregations history from json " + (end-start)+"ms");
326
            return aggregationHistory.size() == 0? aggregationHistory : aggregationHistory.stream()
327
                                                    .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
328
                                                    .limit(size)
329
                                                    .collect(Collectors.toList());
330
        } catch (JSONException e) {
331
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
332
            emailUtils.reportException(e);
333
            throw e;
334
        }
335

    
336
    }
337

    
338
    @Override
339
    public Map<String, List<AggregationDetails>> getRepositoryAggregationsByYear(String id) throws JSONException {
340
        LOGGER.debug("Retreiving aggregations (by year) for repository with id : " + id );
341
        UriComponents uriComponents = searchDatasource("0","100");
342
        RequestFilter requestFilter = new RequestFilter();
343
        requestFilter.setId(id);
344

    
345
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
346
        Map<String, List<AggregationDetails>> aggregationByYear = new HashMap<>();
347
        try {
348
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
349
            JSONObject repository = new JSONObject(rs);
350

    
351
            if(repository.getJSONArray("datasourceInfo").length() == 0)
352
                return aggregationByYear;
353

    
354
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
355
            return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory);
356

    
357
        } catch (JSONException e) {
358
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
359
            emailUtils.reportException(e);
360
            throw e;
361
        }
362
    }
363

    
364
    private Map<String,List<AggregationDetails>> createYearMap(List<AggregationDetails> aggregationHistory) {
365
        Map<String, List<AggregationDetails>> aggregationByYear;
366
        aggregationHistory = aggregationHistory.stream()
367
                            .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
368
                            .collect(Collectors.toList());
369

    
370
       return aggregationHistory.stream()
371
                            .collect(Collectors.groupingBy(AggregationDetails::getYear));
372
    }
373

    
374

    
375
    @Override
376
    public List<Repository> getRepositoriesByName(String name,
377
                                                  String page,
378
                                                  String size) throws JSONException {
379

    
380
        LOGGER.debug("Retreiving  repositories with official name : " + name );
381
        UriComponents uriComponents = searchDatasource("0","100");
382
        RequestFilter requestFilter = new RequestFilter();
383
        requestFilter.setOfficialname(name);
384

    
385
        try{
386
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
387
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
388
            for (Repository r : repos)
389
                updateRepositoryInfo(r);
390
            return repos;
391
        }catch (Exception e){
392
            LOGGER.debug("Exception on getRepositoriesByName" , e);
393
            emailUtils.reportException(e);
394
            throw e;
395
        }
396

    
397
    }
398

    
399
    @Override
400
    public List<RepositoryInterface> getRepositoryInterface(String id) throws JSONException {
401

    
402
        UriComponents uriComponents = UriComponentsBuilder
403
                .fromHttpUrl(baseAddress + "/ds/api/")
404
                .path("/{id}")
405
                .build().expand(id).encode();
406

    
407
        try{
408
            String rs = restTemplate.getForObject(uriComponents.toUri(), String.class);
409
            return Converter.jsonToRepositoryInterfaceList(new JSONObject(rs));
410
        }catch (Exception e ){
411
            LOGGER.debug("Exception on getRepositoryInterface" , e);
412
            emailUtils.reportException(e);
413
            throw e;
414
        }
415

    
416
    }
417

    
418
    @Override
419
    public Repository addRepository(String datatype,
420
                                    Repository repository) throws Exception {
421

    
422
        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
423

    
424
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
425
        repository.setActivationId(UUID.randomUUID().toString());
426
        repository.setCollectedFrom("infrastruct_::openaire");
427

    
428
        if (datatype.equals("journal")) {
429
            repository.setId("openaire____::issn" + repository.getIssn());
430
            repository.setNamespacePrefix("issn" + repository.getIssn());
431
            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
432
        }else if (datatype.equals("aggregator")) {
433
            repository.setId("openaire____::" + com.unboundid.util.Base64.encode(repository.getOfficialName()));
434
            repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0,12));
435
            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
436
        }else {
437
            this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication());
438
        }
439

    
440
        return repository;
441
    }
442

    
443
    /* update method acting as add -> send email with registration topic/body*/
444
    private Repository latentUpdate(Repository repository, Authentication authentication) throws Exception {
445
        UriComponents uriComponents = UriComponentsBuilder
446
                .fromHttpUrl(baseAddress + "/ds/update/")
447
                .build()
448
                .encode();
449

    
450
        try {
451
            String json_repository = Converter.repositoryObjectToJson(repository);
452
            LOGGER.debug("JSON to add(update) -> " + json_repository);
453

    
454
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
455
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
456

    
457
            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
458
                emailUtils.sendUserRegistrationEmail(repository, authentication);
459
                emailUtils.sendAdminRegistrationEmail(repository, authentication);
460
            } else
461
                LOGGER.debug(responseEntity.getBody().toString());
462

    
463
            return repository;
464
        } catch (Exception e) {
465
            LOGGER.debug("Exception on updateRepository" , e);
466
            emailUtils.reportException(e);
467
            throw e;
468
        }
469

    
470

    
471
    }
472

    
473
    @Override
474
    public Repository updateRepository(Repository repository,Authentication authentication) throws Exception {
475
        UriComponents uriComponents = UriComponentsBuilder
476
                .fromHttpUrl(baseAddress + "/ds/update/")
477
                .build()
478
                .encode();
479

    
480
        try {
481
            String json_repository = Converter.repositoryObjectToJson(repository);
482

    
483
            LOGGER.debug("JSON to update -> " + json_repository);
484

    
485
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
486
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity
487
                    , ResponseEntity.class);
488

    
489
            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
490
                emailUtils.sendUserUpdateRepositoryEmail(repository, authentication);
491
                emailUtils.sendAdminUpdateRepositoryEmail(repository, authentication);
492
            } else
493
                LOGGER.debug(responseEntity.getBody().toString());
494

    
495
            return repository;
496
        } catch (Exception e) {
497
            LOGGER.debug("Exception on updateRepository" , e);
498
            emailUtils.reportException(e);
499
            throw e;
500
        }
501
    }
502

    
503
    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
504

    
505
        Date utilDate = new Date();
506
        Timestamp date = new Timestamp(utilDate.getTime());
507
        repository.setDateOfCollection(date);
508
        repository.setAggregator("OPENAIRE");
509
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
510

    
511
        UriComponents uriComponents = UriComponentsBuilder
512
                .fromHttpUrl(baseAddress + "/ds/add/")
513
                .build()
514
                .encode();
515
        String json_repository = Converter.repositoryObjectToJson(repository);
516
        HttpEntity<String> httpEntity = new HttpEntity <String> (json_repository,httpHeaders);
517
        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
518

    
519
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)) {
520
            emailUtils.sendUserRegistrationEmail(repository, authentication);
521
            emailUtils.sendAdminRegistrationEmail(repository, authentication);
522
        } else {
523
            LOGGER.debug(responseEntity.getBody().toString());
524
        }
525
    }
526

    
527
    @Override
528
    public void deleteRepositoryInterface(String id ,
529
                                          String registeredBy){
530
        UriComponents uriComponents = UriComponentsBuilder
531
                .fromHttpUrl(baseAddress + "/ds/api/")
532
                .path("/{id}")
533
                .build().expand(id).encode();
534
        LOGGER.debug(uriComponents.toUri());
535
        restTemplate.delete(uriComponents.toUri());
536
    }
537

    
538
    @Override
539
    public RepositoryInterface addRepositoryInterface(String datatype,
540
                                                      String repoId,
541
                                                      String registeredBy,
542
                                                      RepositoryInterface repositoryInterface) throws JSONException, ResourceNotFoundException, ValidatorServiceException {
543
        try {
544
            Repository e = this.getRepositoryById(repoId);
545
            repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype);
546
            String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface);
547

    
548
            UriComponents uriComponents = UriComponentsBuilder
549
                    .fromHttpUrl(baseAddress + "/ds/api/add/")
550
                    .build()
551
                    .encode();
552

    
553
            HttpEntity<String> httpEntity = new HttpEntity <> (json_interface,httpHeaders);
554
            restTemplate.postForObject(uriComponents.toUri(),httpEntity,String.class);
555
            submitInterfaceValidation(e, registeredBy, repositoryInterface, false);
556

    
557
            return repositoryInterface;
558

    
559
        } catch (JSONException | ValidatorServiceException e) {
560
            LOGGER.debug("Exception on addRepositoryInterface" , e);
561
            emailUtils.reportException(e);
562
            throw e;
563
        }
564
    }
565

    
566
    @Override
567
    public RepositoryInterface updateRepositoryInterface(String repoId,
568
                                                         String registeredBy,
569
                                                         RepositoryInterface repositoryInterface) throws Exception {
570

    
571
        this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl());
572
        this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance());
573
        this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet());
574
        submitInterfaceValidation(getRepositoryById(repoId),registeredBy,repositoryInterface,true);
575
        return repositoryInterface;
576
    }
577

    
578
    private void submitInterfaceValidation(Repository repo, String userEmail, RepositoryInterface iFace, boolean updateExisting) throws ValidatorServiceException {
579
        JobForValidation job = new JobForValidation();
580

    
581
        job.setActivationId(UUID.randomUUID().toString());
582
        job.setAdminEmails(Collections.singletonList(this.adminEmail));
583
        job.setBaseUrl(iFace.getBaseUrl());
584
        job.setDatasourceId(repo.getId());
585
        job.setDesiredCompatibilityLevel(iFace.getDesiredCompatibilityLevel());
586
        job.setInterfaceId(iFace.getId());
587
        job.setOfficialName(repo.getOfficialName());
588
        job.setRepoType(repo.getDatasourceType());
589
        job.setUserEmail(userEmail);
590
        job.setValidationSet((iFace.getAccessSet().isEmpty() ? "none" : iFace.getAccessSet()));
591
        job.setRecords(-1);
592
        job.setRegistration(!updateExisting);
593
        job.setUpdateExisting(updateExisting);
594

    
595
        this.validatorService.submitJobForValidation(job);
596
    }
597

    
598
    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
599

    
600
        iFace.setContentDescription("metadata");
601
        iFace.setCompliance("UNKNOWN");
602

    
603
        if (datatype.equals("re3data"))
604
            iFace.setAccessFormat("oai_datacite");
605
        else
606
            iFace.setAccessFormat("oai_dc");
607

    
608

    
609
        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
610
            iFace.setTypology(repo.getDatasourceClass());
611
        else if (datatype.equalsIgnoreCase("journal"))
612
            iFace.setTypology("pubsrepository::journal");
613
        else if (datatype.equalsIgnoreCase("aggregator"))
614
            iFace.setTypology("aggregator::pubsrepository::unknown");
615
        else if (datatype.equalsIgnoreCase("opendoar"))
616
            iFace.setTypology("pubsrepository::unknown");
617
        else if (datatype.equalsIgnoreCase("re3data"))
618
            iFace.setTypology("datarepository::unknown");
619

    
620
        iFace.setRemovable(true);
621
        iFace.setAccessProtocol("oai");
622
        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
623
        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
624
        if (iFace.getAccessSet() == null || iFace.getAccessSet().isEmpty()) {
625
            LOGGER.debug("set is empty: " + iFace.getAccessSet());
626
            iFace.removeAccessSet();
627
            iFace.setAccessSet("none");
628
        }
629
        return iFace;
630
    }
631

    
632
    @Override
633
    public List<String> getDnetCountries() {
634
        LOGGER.debug("Getting dnet-countries!");
635
        return Converter.readFile("countries.txt");
636
    }
637

    
638
    @Override
639
    public List<String> getTypologies() {
640
        return Converter.readFile("typologies.txt");
641
    }
642

    
643
    @Override
644
    public List<Timezone> getTimezones() {
645
        List<String> timezones =  Converter.readFile("timezones.txt");
646
        return Converter.toTimezones(timezones);
647
    }
648

    
649
    @Override
650
    public List<String> getUrlsOfUserRepos(String userEmail,
651
                                           String page,
652
                                           String size){
653
        UriComponents uriComponents = UriComponentsBuilder
654
                .fromHttpUrl(baseAddress + "/api/baseurl/")
655
                .path("/{page}/{size}")
656
                .build().expand(page,size).encode();
657

    
658
        try{
659
            RequestFilter requestFilter = new RequestFilter();
660
            requestFilter.setRegisteredby(userEmail);
661
            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class));
662
        }catch (Exception e){
663
            LOGGER.debug("Exception on addRepositoryInterface" , e);
664
            emailUtils.reportException(e);
665
            throw e;
666
        }
667
    }
668

    
669
    @Override
670
    public List<String> getDatasourceVocabularies(String mode) {
671

    
672
        List<String> resultSet = new ArrayList<>();
673
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
674
            if (mode.equalsIgnoreCase("aggregator")) {
675
                if (entry.getKey().contains("aggregator"))
676
                    resultSet.add(entry.getValue());
677
            } else if (mode.equalsIgnoreCase("journal")) {
678
                if (entry.getKey().contains("journal"))
679
                    resultSet.add(entry.getValue());
680
            } else if (mode.equalsIgnoreCase("opendoar")) {
681
                if (entry.getKey().contains("pubsrepository"))
682
                    resultSet.add(entry.getValue());
683
            } else if (mode.equalsIgnoreCase("re3data")) {
684
                if (entry.getKey().contains("datarepository"))
685
                    resultSet.add(entry.getValue());
686
            }
687
        }
688

    
689

    
690
        return resultSet;
691
    }
692

    
693
    private Vocabulary getVocabulary(String vocName) {
694

    
695
        if (!vocabularyMap.containsKey(vocName)) {
696
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
697
        }
698
        return vocabularyMap.get(vocName);
699
    }
700

    
701

    
702
    @Override
703
    public Map<String, String> getCompatibilityClasses(String mode)  {
704

    
705
        LOGGER.debug("Getting compatibility classes for mode: " + mode);
706
        Map<String, String> retMap = new HashMap<String, String>();
707

    
708
        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
709
        boolean foundData = false;
710
        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
711
            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
712
                return compatibilityClasses;
713
            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
714
                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
715
                    retMap.put(entry.getKey(), entry.getValue());
716
                    foundData = true;
717
                }
718
            } else {
719
                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
720
                    retMap.put(entry.getKey(), entry.getValue());
721
            }
722
        }
723

    
724
        //TODO TO BE REMOVED WHEN VOCABULARIES ARE UPDATED
725
        if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA) && !foundData)
726
            retMap.put("openaire2.0_data", "OpenAIRE Data (funded, referenced datasets)");
727

    
728
        return retMap;
729
    }
730

    
731
    @Override
732
    public Map<String, String> getDatasourceClasses(String mode)  {
733

    
734
        LOGGER.debug("Getting datasource classes for mode: " + mode);
735

    
736
        Map<String, String> retMap = new HashMap<String, String>();
737

    
738
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
739
            if (mode.equalsIgnoreCase("aggregator")) {
740
                if (entry.getKey().contains("aggregator"))
741
                    retMap.put(entry.getKey(), entry.getValue());
742
            } else if (mode.equalsIgnoreCase("journal")) {
743
                if (entry.getKey().contains("journal"))
744
                    retMap.put(entry.getKey(), entry.getValue());
745
            } else if (mode.equalsIgnoreCase("opendoar")) {
746
                if (entry.getKey().contains("pubsrepository"))
747
                    retMap.put(entry.getKey(), entry.getValue());
748
            } else if (mode.equalsIgnoreCase("re3data")) {
749
                if (entry.getKey().contains("datarepository"))
750
                    retMap.put(entry.getKey(), entry.getValue());
751
            }
752
        }
753
        return filterResults(retMap,mode);
754

    
755
    }
756

    
757
    private Map<String,String> filterResults(Map<String, String> map,String mode) {
758

    
759
        HashMap<String,String> filteredMap = new HashMap<>();
760
        for(String key:map.keySet())
761
            if(dataSourceClass.get(mode).contains(key))
762
                filteredMap.put(key,map.get(key));
763

    
764
        return filteredMap;
765
    }
766

    
767
    @Override
768
    public String getCountryName(String countryCode) {
769
        return inverseCountriesMap.get(countryCode);
770
    }
771

    
772
    @Override
773
    public MetricsInfo getMetricsInfoForRepository(String repoId) throws RepositoryServiceException {
774
        try {
775

    
776
            MetricsInfo metricsInfo = new MetricsInfo();
777
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
778
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
779
            return metricsInfo;
780

    
781
        } catch (Exception e) {
782
            LOGGER.error("Error while getting metrics info for repository: ", e);
783
            emailUtils.reportException(e);
784
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
785
        }
786
    }
787

    
788
    @Override
789
    public Map<String, String> getListLatestUpdate(String mode) throws JSONException {
790
        if(mode.equals("opendoar"))
791
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate());
792
        else
793
            /*
794
            * first api of re3data has null value on collection date
795
            * */
796
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
797
    }
798

    
799
    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
800
        UriComponents uriComponents = UriComponentsBuilder
801
                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
802
                .queryParam("dsId",repositoryId)
803
                .queryParam("apiId",repositoryInterfaceId)
804
                .queryParam("oaiSet",validationSet)
805
                .build().encode();
806
       restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, null, ResponseEntity.class);
807

    
808
    }
809

    
810

    
811
    private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) {
812
        UriComponents uriComponents = UriComponentsBuilder
813
                .fromHttpUrl(baseAddress + "/ds/api/baseurl")
814
                .queryParam("dsId",repositoryId)
815
                .queryParam("apiId",repositoryInterfaceId)
816
                .queryParam("baseUrl",baseUrl)
817
                .build().encode();
818
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
819
    }
820

    
821
    private void updateCompliance(String repositoryId, String repositoryInterfaceId,String compliance) {
822
        UriComponents uriComponents = UriComponentsBuilder
823
                .fromHttpUrl(baseAddress + "/ds/api/compliance")
824
                .queryParam("dsId",repositoryId)
825
                .queryParam("apiId",repositoryInterfaceId)
826
                .queryParam("compliance",compliance)
827
                .build().encode();
828
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
829
    }
830

    
831
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
832

    
833
        //build the uri params
834
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
835

    
836
        //create new template engine
837
        RestTemplate template = new RestTemplate();
838
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
839
        ResponseEntity<MetricsNumbers> resp;
840
        try {
841
            //communicate with endpoint
842
            resp = template.exchange(
843
                    builder.build().encode().toUri(),
844
                    HttpMethod.GET,
845
                    null,
846
                    new ParameterizedTypeReference<MetricsNumbers>() {
847
                    });
848
        } catch (RestClientException e) {
849
            LOGGER.debug("Exception on getMetricsNumbers" , e);
850
            emailUtils.reportException(e);
851
            throw e;
852
        }
853

    
854
        return resp.getBody();
855
    }
856

    
857
    private String getOpenAIREId(String repoId) {
858

    
859
        if (repoId != null && repoId.contains("::")) {
860
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
861
        }
862

    
863
        return null;
864
    }
865

    
866
    private UriComponents searchDatasource(String page,String size){
867

    
868
        return UriComponentsBuilder
869
                .fromHttpUrl(baseAddress + "/ds/search/")
870
                .path("/{page}/{size}/")
871
                .queryParam("requestSortBy","officialname")
872
                .queryParam("order","ASCENDING")
873
                .build().expand(page, size).encode();
874
    }
875

    
876
    private UriComponents searchSnipperDatasource(String page,String size){
877

    
878
        return UriComponentsBuilder
879
                .fromHttpUrl(baseAddress + "/ds/searchsnippet/")
880
                .path("/{page}/{size}/")
881
                .queryParam("requestSortBy","officialname")
882
                .queryParam("order","ASCENDING")
883
                .build().expand(page, size).encode();
884
    }
885

    
886
    private UriComponents searchRegisteredDatasource(String requestSortBy, String order, String page,String size){
887

    
888
        return UriComponentsBuilder
889
                .fromHttpUrl(baseAddress + "/ds/searchregistered/")
890
                .path("/{page}/{size}/")
891
                .queryParam("requestSortBy",requestSortBy)
892
                .queryParam("order",order)
893
                .build().expand(page, size).encode();
894
    }
895

    
896
    private String getRepositoryType(String typology){
897
        return invertedDataSourceClass.get(typology);
898
    }
899

    
900

    
901
}
(12-12/20)