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.domain.data.Repository;
7
import eu.dnetlib.domain.data.RepositoryInterface;
8
import eu.dnetlib.domain.enabling.Vocabulary;
9
import eu.dnetlib.repo.manager.domain.RepositorySnippet;
10
import eu.dnetlib.repo.manager.domain.RequestFilter;
11
import eu.dnetlib.repo.manager.exception.ResourceNotFoundException;
12
import eu.dnetlib.repo.manager.utils.Converter;
13
import eu.dnetlib.repo.manager.shared.*;
14
import gr.uoa.di.driver.enabling.vocabulary.VocabularyLoader;
15
import org.apache.commons.codec.digest.DigestUtils;
16
import org.apache.log4j.Logger;
17
import org.json.JSONArray;
18
import org.json.JSONException;
19
import org.json.JSONObject;
20
import org.springframework.beans.factory.annotation.Autowired;
21
import org.springframework.beans.factory.annotation.Value;
22
import org.springframework.core.ParameterizedTypeReference;
23
import org.springframework.http.*;
24
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
25
import org.springframework.security.access.prepost.PreAuthorize;
26
import org.springframework.security.core.Authentication;
27
import org.springframework.security.core.context.SecurityContextHolder;
28
import org.springframework.stereotype.Service;
29
import org.springframework.web.bind.annotation.PathVariable;
30
import org.springframework.web.bind.annotation.RequestBody;
31
import org.springframework.web.bind.annotation.RequestParam;
32
import org.springframework.web.client.RestClientException;
33
import org.springframework.web.client.RestTemplate;
34
import org.springframework.web.util.UriComponents;
35
import org.springframework.web.util.UriComponentsBuilder;
36

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

    
44
@Service("repositoryService")
45
public class RepositoryApiImpl implements RepositoryApi {
46

    
47
    @Value("${api.baseAddress}")
48
    private String baseAddress;
49

    
50
    private RestTemplate restTemplate = null;
51

    
52
    private HttpHeaders httpHeaders;
53

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

    
56
    private static final Logger LOGGER = Logger.getLogger(RepositoryApiImpl.class);
57

    
58
    @Value("${services.repomanager.usageStatisticsDiagramsBaseURL}")
59
    private String usageStatisticsDiagramsBaseURL;
60

    
61
    @Value("${services.repomanager.usageStatisticsNumbersBaseURL}")
62
    private String usageStatisticsNumbersBaseURL;
63

    
64
    @Autowired
65
    private VocabularyLoader vocabularyLoader;
66

    
67
    @Autowired
68
    private PiWikApi piWikApi;
69

    
70
    @Autowired
71
    private EmailUtils emailUtils;
72

    
73
    private Map<String, Vocabulary> vocabularyMap = new ConcurrentHashMap<String, Vocabulary>();
74

    
75
    private Map<String, String> countriesMap = new HashMap<>();
76
    private Map<String, String> inverseCountriesMap = new HashMap<>();
77

    
78
    private static Map<String,List<String>> dataSourceClass = new HashMap<String,List<String>>(){{
79
        put("opendoar",new ArrayList<String>(){{ add("pubsrepository::institutional");
80
                                                    add("pubsrepository::thematic");
81
                                                    add("pubsrepository::unknown");
82
                                                    add("pubsrepository::mock");
83
        }});
84
        put("re3data",new ArrayList<String>(){{ add("datarepository::unknown");
85
        }});
86
        put("journal",new ArrayList<String>(){{ add("pubsrepository::journal");
87
        }});
88
        put("aggregator",new ArrayList<String>(){{ add("aggregator::pubsrepository::institutional");
89
                                                        add("aggregator::pubsrepository::journals");
90
                                                        add("aggregator::datarepository");
91
                                                        add("aggregator::pubsrepository::unknown");
92
        }});
93
    }};
94

    
95
    private static Map<String,String> invertedDataSourceClass = new HashMap<String,String>(){{
96
        put("pubsrepository::institutional","opendoar");
97
        put("pubsrepository::thematic","opendoar");
98
        put("pubsrepository::unknown","opendoar");
99
        put("pubsrepository::mock","opendoar");
100

    
101
        put("datarepository::unknown","re3data");
102

    
103
        put("pubsrepository::journal","journal");
104

    
105
        put("aggregator::pubsrepository::institutional","aggregator");
106
        put("aggregator::pubsrepository::journals","aggregator");
107
        put("aggregator::datarepository","aggregator");
108
        put("aggregator::pubsrepository::unknown","aggregator");
109

    
110
    }};
111

    
112

    
113

    
114
    @PostConstruct
115
    private void init() {
116
        LOGGER.debug("Initialization method of repository api!");
117
        LOGGER.debug("Updated version!");
118

    
119
        restTemplate = new RestTemplate();
120
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
121

    
122
        httpHeaders = new HttpHeaders();
123
        httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
124

    
125
        for (String vocName : vocabularyNames) {
126
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
127
        }
128

    
129
        Country[] countries = getCountries();
130
        for (Country c : countries) {
131
            countriesMap.put(c.getName(), c.getCode());
132
            inverseCountriesMap.put(c.getCode(), c.getName());
133
        }
134

    
135

    
136
    }
137

    
138
    @Override
139
    public Country[] getCountries() {
140
        UriComponents uriComponents = UriComponentsBuilder
141
                .fromHttpUrl(baseAddress + "/ds/countries")
142
                .build().encode();
143
        return restTemplate.getForObject(uriComponents.toUri(), Country[].class);
144
    }
145

    
146

    
147
    @Override
148
    public List<RepositorySnippet> getRepositoriesByCountry(@PathVariable("country") String country,
149
                                                            @PathVariable("mode") String mode,
150
                                                            @RequestParam(value = "managed",required=false) Boolean managed) throws JSONException, IOException {
151

    
152
        LOGGER.debug("Getting repositories by country!");
153
        int page = 0;
154
        int size = 100;
155
        List<RepositorySnippet> resultSet = new ArrayList<>();
156
        ObjectMapper mapper = new ObjectMapper();
157

    
158
        String filterKey = "UNKNOWN";
159
        if (mode.equalsIgnoreCase("opendoar"))
160
            filterKey = "openaire____::opendoar";
161
        else if (mode.equalsIgnoreCase("re3data"))
162
            filterKey = "openaire____::re3data";
163

    
164

    
165
        LOGGER.debug("Country code equals : " + country);
166
        LOGGER.debug("Filter mode equals : " + filterKey);
167

    
168
        UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size));
169
        RequestFilter requestFilter = new RequestFilter();
170
        requestFilter.setCountry(country);
171
        requestFilter.setCollectedfrom(filterKey);
172

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

    
191

    
192
    }
193

    
194
    private Repository updateRepositoryInfo(Repository r) throws JSONException {
195

    
196
        /*
197
        * from datasource class
198
        * we get the datasource type form the inverted map
199
        * */
200
        r.setDatasourceType(getRepositoryType(r.getDatasourceClass()));
201
        r.setInterfaces(this.getRepositoryInterface(r.getId()));
202
        r.setPiwikInfo(piWikApi.getPiwikSiteForRepo(r.getId()));
203
        r.setCountryName(getCountryName(r.getCountryCode()));
204
        return r;
205
    }
206

    
207

    
208
    private Collection<Repository> getRepositoriesByMode(String mode, List<Repository> rs) {
209

    
210
        List<Repository> reps = new ArrayList<>();
211
        for (Repository r : rs) {
212
            if (r.getCollectedFrom() != null && r.getCollectedFrom().equals(mode))
213
                reps.add(r);
214

    
215
        }
216
        return reps;
217
    }
218

    
219
    @Override
220
    @PreAuthorize("hasRole('ROLE_USER')")
221
    public List<Repository> getRepositoriesOfUser(@PathVariable("userEmail") String userEmail,
222
                                                  @PathVariable("page") String page,
223
                                                  @PathVariable("size") String size) throws JSONException {
224

    
225
        LOGGER.debug("Retreiving repositories of user : " + userEmail );
226
        UriComponents uriComponents = searchDatasource(page,size);
227
        RequestFilter requestFilter = new RequestFilter();
228
        requestFilter.setRegisteredby(userEmail);
229

    
230
        try{
231
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
232

    
233
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
234
            for (Repository r : repos)
235
                this.updateRepositoryInfo(r);
236

    
237
            return repos;
238
        }catch (Exception e){
239
            LOGGER.debug("Exception on getRepositoriesOfUser" , e);
240
            emailUtils.reportException(e);
241
            throw e;
242
        }
243
    }
244

    
245
    @Override
246
    public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException,ResourceNotFoundException {
247

    
248
        LOGGER.debug("Retreiving repositories with id : " + id );
249
        Repository repo = null;
250
        UriComponents uriComponents = searchDatasource("0","100");
251
        RequestFilter requestFilter = new RequestFilter();
252
        requestFilter.setId(id);
253

    
254
        try{
255
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
256
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
257

    
258
            if(jsonArray.length() == 0)
259
                throw new ResourceNotFoundException();
260

    
261
            repo = Converter.jsonToRepositoryObject(jsonArray.getJSONObject(0));
262
            return updateRepositoryInfo(repo);
263
        }catch (JSONException e){
264
            LOGGER.debug("Exception on getRepositoryById" , e);
265
            emailUtils.reportException(e);
266
            throw e;
267
        }
268

    
269
    }
270

    
271

    
272
    @Override
273
    public List<AggregationDetails> getRepositoryAggregations(@PathVariable("id") String id) throws JSONException {
274

    
275
        LOGGER.debug("Retreiving aggregations for repository with id : " + id );
276
        UriComponents uriComponents = searchDatasource("0","100");
277
        RequestFilter requestFilter = new RequestFilter();
278
        requestFilter.setId(id);
279

    
280
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
281

    
282
        try {
283
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
284
            JSONObject repository = new JSONObject(rs);
285
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
286
            return aggregationHistory.size() == 0? aggregationHistory : aggregationHistory.stream()
287
                                                    .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
288
                                                    .limit(20)
289
                                                    .collect(Collectors.toList());
290
        } catch (JSONException e) {
291
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
292
            emailUtils.reportException(e);
293
            throw e;
294
        }
295

    
296
    }
297

    
298
    @Override
299
    public Map<String, List<AggregationDetails>> getRepositoryAggregationsByYear(@PathVariable("id") String id) throws JSONException {
300
        LOGGER.debug("Retreiving aggregations (by year) for repository with id : " + id );
301
        UriComponents uriComponents = searchDatasource("0","100");
302
        RequestFilter requestFilter = new RequestFilter();
303
        requestFilter.setId(id);
304

    
305
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
306
        Map<String, List<AggregationDetails>> aggregationByYear = new HashMap<>();
307
        try {
308
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
309
            JSONObject repository = new JSONObject(rs);
310
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
311
            return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory);
312

    
313
        } catch (JSONException e) {
314
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
315
            emailUtils.reportException(e);
316
            throw e;
317
        }
318
    }
319

    
320
    private Map<String,List<AggregationDetails>> createYearMap(List<AggregationDetails> aggregationHistory) {
321
        Map<String, List<AggregationDetails>> aggregationByYear;
322
        aggregationHistory = aggregationHistory.stream()
323
                            .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
324
                            .collect(Collectors.toList());
325

    
326
       return aggregationHistory.stream()
327
                            .collect(Collectors.groupingBy(AggregationDetails::getYear));
328
    }
329

    
330

    
331
    @Override
332
    public List<Repository> getRepositoriesByName(@PathVariable("name") String name,
333
                                                  @PathVariable("page") String page,
334
                                                  @PathVariable("size") String size) throws JSONException {
335

    
336
        LOGGER.debug("Retreiving  repositories with official name : " + name );
337
        UriComponents uriComponents = searchDatasource("0","100");
338
        RequestFilter requestFilter = new RequestFilter();
339
        requestFilter.setOfficialname(name);
340

    
341
        try{
342
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
343
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
344
            for (Repository r : repos)
345
                updateRepositoryInfo(r);
346
            return repos;
347
        }catch (Exception e){
348
            LOGGER.debug("Exception on getRepositoriesByName" , e);
349
            emailUtils.reportException(e);
350
            throw e;
351
        }
352

    
353
    }
354

    
355
    @Override
356
    public List<RepositoryInterface> getRepositoryInterface(@PathVariable("id") String id) throws JSONException {
357

    
358
        UriComponents uriComponents = UriComponentsBuilder
359
                .fromHttpUrl(baseAddress + "/ds/api/")
360
                .path("/{id}")
361
                .build().expand(id).encode();
362

    
363
        try{
364
            String rs = restTemplate.getForObject(uriComponents.toUri(), String.class);
365
            return Converter.jsonToRepositoryInterfaceList(new JSONObject(rs));
366
        }catch (Exception e ){
367
            LOGGER.debug("Exception on getRepositoryInterface" , e);
368
            emailUtils.reportException(e);
369
            throw e;
370
        }
371

    
372
    }
373

    
374
    @Override
375
    @PreAuthorize("hasRole('ROLE_USER') and #repository.registeredBy == authentication.userInfo.email")
376
    public Repository addRepository(@RequestParam("datatype") String datatype,
377
                                    @RequestBody Repository repository) throws Exception {
378

    
379
        repository = this.setRepositoryFeatures(datatype,repository);
380
        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
381
        this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
382
        return repository;
383
    }
384

    
385
    @Override
386
    //@PreAuthorize("hasRole('ROLE_USER') and #repository.registeredBy == authentication.userInfo.email")
387
    public Repository updateRepository(@RequestBody Repository repository,Authentication authentication) throws Exception {
388
        UriComponents uriComponents = UriComponentsBuilder
389
                .fromHttpUrl(baseAddress + "/ds/update/")
390
                .build()
391
                .encode();
392

    
393
        try {
394
            String json_repository = Converter.repositoryObjectToJson(repository);
395

    
396
            LOGGER.debug("JSON to update -> " + json_repository);
397

    
398
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
399
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
400

    
401
            if (responseEntity.getStatusCode().equals(HttpStatus.OK))
402
                emailUtils.sendUserUpdateRepositoryEmail(repository, authentication);
403
            else
404
                LOGGER.debug(responseEntity.getBody().toString());
405

    
406
            return repository;
407
        } catch (Exception e) {
408
            LOGGER.debug("Exception on updateRepository" , e);
409
            emailUtils.reportException(e);
410
            throw e;
411
        }
412
    }
413

    
414
    private Repository setRepositoryFeatures(String datatype, Repository repository) {
415

    
416
        //TODO update map
417
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
418
        repository.setActivationId(UUID.randomUUID().toString());
419
        repository.setCollectedFrom("infrastruct_::openaire");
420

    
421
        if (datatype.equals("journal")) {
422
            repository.setId("openaire____::issn" + repository.getIssn());
423
            repository.setNamespacePrefix("issn" + repository.getIssn());
424
        }else if (datatype.equals("aggregator")) {
425
            repository.setId("openaire____::" + com.unboundid.util.Base64.encode(repository.getOfficialName()));
426
            repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0,12));
427
        }
428

    
429
        return repository;
430
    }
431

    
432
    private void updateInterface(String datatype,RepositoryInterface iFace) {
433
        //TODO call update base url
434
        //((DatasourceManagerService) this.dmService.getService()).updateBaseUrl(repo.getId(), iFace.getId(), iFace.getBaseUrl());
435
        if (!iFace.getAccessSet().isEmpty()) {
436
            LOGGER.debug("set not empty: " + iFace.getAccessSet());
437
            //TODO call update method for access params
438
            // ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "set", iFace.getAccessSet(), false);
439
        } else {
440
            //TODO call deleteAccessParamOrExtraField
441
            //((DatasourceManagerService) this.dmService.getService()).deleteAccessParamOrExtraField(repo.getId(), iFace.getId(), "set");
442
        }
443
        //TODO update content description
444
        //((DatasourceManagerService) this.dmService.getService()).updateContentDescription(repo.getId(), iFace.getId(), "metadata");
445
        if (datatype.equals("re3data")) {
446
            //TODO call update access params
447
            //  ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_datacite", false);
448
            iFace.setAccessFormat("oai_datacite");
449
        } else {
450
            //TODO call update access params
451
            //((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_dc", false);
452
            iFace.setAccessFormat("oai_dc");
453
        }
454

    
455
    }
456

    
457
    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
458

    
459
        Date utilDate = new Date();
460
        Timestamp date = new Timestamp(utilDate.getTime());
461
        repository.setDateOfCollection(date);
462
        repository.setAggregator("OPENAIRE");
463
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
464

    
465
        UriComponents uriComponents = UriComponentsBuilder
466
                .fromHttpUrl(baseAddress + "/ds/add/")
467
                .build()
468
                .encode();
469

    
470
        
471
        String json_repository = Converter.repositoryObjectToJson(repository);
472

    
473
        ObjectMapper mapper = new ObjectMapper();
474
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
475
        try {
476
            LOGGER.debug(mapper.writeValueAsString(json_repository));
477
        } catch (JsonProcessingException e) {
478
            e.printStackTrace();
479
        }
480

    
481
        HttpEntity<String> httpEntity = new HttpEntity <String> (json_repository,httpHeaders);
482
        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
483

    
484
        if(responseEntity.getStatusCode().equals(HttpStatus.OK))
485
            emailUtils.sendUserRegistrationEmail(repository,authentication);
486
        else {
487
            LOGGER.debug(responseEntity.getBody().toString());
488
        }
489
    }
490

    
491
    @Override
492
    @PreAuthorize("hasRole('ROLE_USER') and #registeredBy == authentication.userInfo.email")
493
    public void deleteRepositoryInterface(@RequestParam("id") String id ,
494
                                          @RequestParam("registeredBy") String registeredBy){
495
        UriComponents uriComponents = UriComponentsBuilder
496
                .fromHttpUrl(baseAddress + "/ds/api/")
497
                .path("/{id}")
498
                .build().expand(id).encode();
499
        LOGGER.debug(uriComponents.toUri());
500
        restTemplate.delete(uriComponents.toUri());
501
    }
502

    
503
    @Override
504
    @PreAuthorize("hasRole('ROLE_USER') and #registeredBy == authentication.userInfo.email")
505
    public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype,
506
                                                      @RequestParam("repoId") String repoId,
507
                                                      @RequestParam("registeredBy") String registeredBy,
508
                                                      @RequestBody RepositoryInterface repositoryInterface) throws JSONException,ResourceNotFoundException {
509
        try {
510
            Repository e = this.getRepositoryById(repoId);
511
            repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype);
512
            String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface);
513

    
514
            UriComponents uriComponents = UriComponentsBuilder
515
                    .fromHttpUrl(baseAddress + "/ds/api/add/")
516
                    .build()
517
                    .encode();
518

    
519
            HttpEntity<String> httpEntity = new HttpEntity <String> (json_interface,httpHeaders);
520
            restTemplate.postForObject(uriComponents.toUri(),httpEntity,String.class);
521
            return repositoryInterface;
522

    
523
        } catch (JSONException e) {
524
            LOGGER.debug("Exception on addRepositoryInterface" , e);
525
            emailUtils.reportException(e);
526
            throw e;
527
        }
528
    }
529

    
530
    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
531

    
532
        iFace.setContentDescription("metadata");
533
        iFace.setCompliance("UNKNOWN");
534

    
535
        if (datatype.equals("re3data"))
536
            iFace.setAccessFormat("oai_datacite");
537
        else
538
            iFace.setAccessFormat("oai_dc");
539

    
540

    
541
        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
542
            iFace.setTypology(repo.getDatasourceClass());
543
        else if (datatype.equalsIgnoreCase("journal"))
544
            iFace.setTypology("pubsrepository::journal");
545
        else if (datatype.equalsIgnoreCase("aggregator"))
546
            iFace.setTypology("aggregator::pubsrepository::unknown");
547
        else if (datatype.equalsIgnoreCase("opendoar"))
548
            iFace.setTypology("pubsrepository::unknown");
549
        else if (datatype.equalsIgnoreCase("re3data"))
550
            iFace.setTypology("datarepository::unknown");
551

    
552
        iFace.setRemovable(true);
553
        iFace.setAccessProtocol("oai");
554
        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
555
        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
556
        if (iFace.getAccessSet().isEmpty()) {
557
            LOGGER.debug("set is empty: " + iFace.getAccessSet());
558
            iFace.removeAccessSet();
559
        }
560
        return iFace;
561
    }
562

    
563
    @Override
564
    public List<String> getDnetCountries() {
565
        LOGGER.debug("Getting dnet-countries!");
566
        return Converter.readFile("countries.txt");
567
    }
568

    
569
    @Override
570
    public List<String> getTypologies() {
571
        return Converter.readFile("typologies.txt");
572
    }
573

    
574
    @Override
575
    public List<Timezone> getTimezones() {
576
        List<String> timezones =  Converter.readFile("timezones.txt");
577
        return Converter.toTimezones(timezones);
578
    }
579

    
580
    @Override
581
    @PreAuthorize("hasRole('ROLE_USER')")
582
    public List<String> getUrlsOfUserRepos(@PathVariable("user_email") String userEmail,
583
                                           @PathVariable("page") String page,
584
                                           @PathVariable("size") String size) throws JSONException {
585
        UriComponents uriComponents = UriComponentsBuilder
586
                .fromHttpUrl(baseAddress + "/api/baseurl/")
587
                .path("/{page}/{size}")
588
                .build().expand(page,size).encode();
589

    
590
        try{
591
            RequestFilter requestFilter = new RequestFilter();
592
            requestFilter.setRegisteredby(userEmail);
593
            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class));
594
        }catch (Exception e){
595
            LOGGER.debug("Exception on addRepositoryInterface" , e);
596
            emailUtils.reportException(e);
597
            throw e;
598
        }
599
    }
600

    
601
    @Override
602
    public List<String> getDatasourceVocabularies(@PathVariable("mode") String mode) {
603

    
604
        List<String> resultSet = new ArrayList<>();
605
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
606
            if (mode.equalsIgnoreCase("aggregator")) {
607
                if (entry.getKey().contains("aggregator"))
608
                    resultSet.add(entry.getValue());
609
            } else if (mode.equalsIgnoreCase("journal")) {
610
                if (entry.getKey().contains("journal"))
611
                    resultSet.add(entry.getValue());
612
            } else if (mode.equalsIgnoreCase("opendoar")) {
613
                if (entry.getKey().contains("pubsrepository"))
614
                    resultSet.add(entry.getValue());
615
            } else if (mode.equalsIgnoreCase("re3data")) {
616
                if (entry.getKey().contains("datarepository"))
617
                    resultSet.add(entry.getValue());
618
            }
619
        }
620

    
621

    
622
        return resultSet;
623
    }
624

    
625
    private Vocabulary getVocabulary(String vocName) {
626

    
627
        if (!vocabularyMap.containsKey(vocName)) {
628
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
629
        }
630
        return vocabularyMap.get(vocName);
631
    }
632

    
633

    
634
    @Override
635
    public Map<String, String> getCompatibilityClasses(@PathVariable("mode") String mode)  {
636

    
637
        LOGGER.debug("Getting compatibility classes for mode: " + mode);
638
        Map<String, String> retMap = new HashMap<String, String>();
639

    
640
        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
641
        boolean foundData = false;
642
        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
643
            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
644
                return compatibilityClasses;
645
            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
646
                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
647
                    retMap.put(entry.getKey(), entry.getValue());
648
                    foundData = true;
649
                }
650
            } else {
651
                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
652
                    retMap.put(entry.getKey(), entry.getValue());
653
            }
654
        }
655

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

    
660
        return retMap;
661
    }
662

    
663
    @Override
664
    public Map<String, String> getDatasourceClasses(@PathVariable("mode") String mode)  {
665

    
666
        LOGGER.debug("Getting datasource classes for mode: " + mode);
667

    
668
        Map<String, String> retMap = new HashMap<String, String>();
669

    
670
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
671
            if (mode.equalsIgnoreCase("aggregator")) {
672
                if (entry.getKey().contains("aggregator"))
673
                    retMap.put(entry.getKey(), entry.getValue());
674
            } else if (mode.equalsIgnoreCase("journal")) {
675
                if (entry.getKey().contains("journal"))
676
                    retMap.put(entry.getKey(), entry.getValue());
677
            } else if (mode.equalsIgnoreCase("opendoar")) {
678
                if (entry.getKey().contains("pubsrepository"))
679
                    retMap.put(entry.getKey(), entry.getValue());
680
            } else if (mode.equalsIgnoreCase("re3data")) {
681
                if (entry.getKey().contains("datarepository"))
682
                    retMap.put(entry.getKey(), entry.getValue());
683
            }
684
        }
685
        return filterResults(retMap,mode);
686

    
687
    }
688

    
689
    private Map<String,String> filterResults(Map<String, String> map,String mode) {
690

    
691
        HashMap<String,String> filteredMap = new HashMap<>();
692
        for(String key:map.keySet())
693
            if(dataSourceClass.get(mode).contains(key))
694
                filteredMap.put(key,map.get(key));
695

    
696
        return filteredMap;
697
    }
698

    
699
    @Override
700
    public String getCountryName(String countryCode) {
701
        return inverseCountriesMap.get(countryCode);
702
    }
703

    
704
    @Override
705
    public MetricsInfo getMetricsInfoForRepository(@PathVariable("repoId")  String repoId) throws RepositoryServiceException {
706
        try {
707

    
708
            MetricsInfo metricsInfo = new MetricsInfo();
709
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
710
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
711
            return metricsInfo;
712

    
713
        } catch (Exception e) {
714
            LOGGER.error("Error while getting metrics info for repository: ", e);
715
            emailUtils.reportException(e);
716
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
717
        }
718
    }
719

    
720
    @Override
721
    public Map<String, String> getListLatestUpdate(@PathVariable("mode")  String mode) throws JSONException {
722
        if(mode.equals("opendoar"))
723
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate());
724
        else
725
            /*
726
            * first api of re3data has null value on collection date
727
            * */
728
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
729
    }
730

    
731
    @Override
732
    @PreAuthorize("hasRole('ROLE_USER') and #registeredBy == authentication.userInfo.email")
733
    public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
734
                                                         @RequestParam("registeredBy") String registeredBy,
735
                                                         @RequestBody RepositoryInterface repositoryInterface) throws JSONException {
736

    
737
        this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl());
738
        this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance());
739
        this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet());
740
        return repositoryInterface;
741
    }
742

    
743
    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) {
744
        UriComponents uriComponents = UriComponentsBuilder
745
                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
746
                .queryParam("dsId",repositoryId)
747
                .queryParam("apiId",repositoryInterfaceId)
748
                .queryParam("oaiSet",validationSet)
749
                .build().encode();
750
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
751
    }
752

    
753

    
754
    private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) {
755
        UriComponents uriComponents = UriComponentsBuilder
756
                .fromHttpUrl(baseAddress + "/ds/api/baseurl")
757
                .queryParam("dsId",repositoryId)
758
                .queryParam("apiId",repositoryInterfaceId)
759
                .queryParam("baseUrl",baseUrl)
760
                .build().encode();
761
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
762
    }
763

    
764
    private void updateCompliance(String repositoryId, String repositoryInterfaceId,String compliance) {
765
        UriComponents uriComponents = UriComponentsBuilder
766
                .fromHttpUrl(baseAddress + "/ds/api/compliance")
767
                .queryParam("dsId",repositoryId)
768
                .queryParam("apiId",repositoryInterfaceId)
769
                .queryParam("compliance",compliance)
770
                .build().encode();
771
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
772
    }
773

    
774
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
775

    
776
        //build the uri params
777
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
778

    
779
        //create new template engine
780
        RestTemplate template = new RestTemplate();
781
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
782
        ResponseEntity<MetricsNumbers> resp;
783
        try {
784
            //communicate with endpoint
785
            resp = template.exchange(
786
                    builder.build().encode().toUri(),
787
                    HttpMethod.GET,
788
                    null,
789
                    new ParameterizedTypeReference<MetricsNumbers>() {
790
                    });
791
        } catch (RestClientException e) {
792
            LOGGER.debug("Exception on getMetricsNumbers" , e);
793
            emailUtils.reportException(e);
794
            throw e;
795
        }
796

    
797
        return resp.getBody();
798
    }
799

    
800
    private String getOpenAIREId(String repoId) {
801

    
802
        if (repoId != null && repoId.contains("::")) {
803
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
804
        }
805

    
806
        return null;
807
    }
808

    
809
    private UriComponents searchDatasource(String page,String size){
810

    
811
        return UriComponentsBuilder
812
                .fromHttpUrl(baseAddress + "/ds/search/")
813
                .path("/{page}/{size}/")
814
                .queryParam("requestSortBy","officialname")
815
                .queryParam("order","ASCENDING")
816
                .build().expand(page, size).encode();
817
    }
818

    
819
    private UriComponents searchSnipperDatasource(String page,String size){
820

    
821
        return UriComponentsBuilder
822
                .fromHttpUrl(baseAddress + "/ds/searchsnippet/")
823
                .path("/{page}/{size}/")
824
                .queryParam("requestSortBy","officialname")
825
                .queryParam("order","ASCENDING")
826
                .build().expand(page, size).encode();
827
    }
828

    
829
    private String getRepositoryType(String typology){
830
        return invertedDataSourceClass.get(typology);
831
    }
832

    
833

    
834
}
(11-11/19)