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.shared.*;
13
import eu.dnetlib.repo.manager.utils.Converter;
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.core.Authentication;
26
import org.springframework.security.core.context.SecurityContextHolder;
27
import org.springframework.stereotype.Service;
28
import org.springframework.web.bind.annotation.PathVariable;
29
import org.springframework.web.bind.annotation.RequestBody;
30
import org.springframework.web.bind.annotation.RequestParam;
31
import org.springframework.web.client.RestClientException;
32
import org.springframework.web.client.RestTemplate;
33
import org.springframework.web.util.UriComponents;
34
import org.springframework.web.util.UriComponentsBuilder;
35

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

    
43
@Service("repositoryService")
44
public class RepositoryServiceImpl implements RepositoryService {
45

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

    
49
    @Autowired
50
    RestTemplate restTemplate;
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(RepositoryServiceImpl.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 PiWikService piWikService;
69

    
70
    @Autowired
71
    private EmailUtils emailUtils;
72

    
73

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

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

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

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

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

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

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

    
111
    }};
112

    
113

    
114

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

    
120
        httpHeaders = new HttpHeaders();
121
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
122
//        httpHeaders.set("Content-Type", "application/json");
123

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

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

    
134

    
135
    }
136

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

    
145

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

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

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

    
163

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

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

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

    
190

    
191
    }
192

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

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

    
206

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

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

    
214
        }
215
        return reps;
216
    }
217

    
218
    @Override
219
    public List<Repository> getRepositoriesOfUser(@PathVariable("userEmail") String userEmail,
220
                                                  @PathVariable("page") String page,
221
                                                  @PathVariable("size") String size) throws JSONException {
222

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

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

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

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

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

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

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

    
256
            if(jsonArray.length() == 0)
257
                throw new ResourceNotFoundException();
258

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

    
267
    }
268

    
269

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

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

    
278
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
279

    
280
        try {
281
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
282
            JSONObject repository = new JSONObject(rs);
283

    
284
            if(repository.getJSONArray("datasourceInfo").length() == 0)
285
                return aggregationHistory;
286
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
287
            return aggregationHistory.size() == 0? aggregationHistory : aggregationHistory.stream()
288
                                                    .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
289
                                                    .limit(20)
290
                                                    .collect(Collectors.toList());
291
        } catch (JSONException e) {
292
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
293
            emailUtils.reportException(e);
294
            throw e;
295
        }
296

    
297
    }
298

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

    
306
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
307
        Map<String, List<AggregationDetails>> aggregationByYear = new HashMap<>();
308
        try {
309
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
310
            JSONObject repository = new JSONObject(rs);
311

    
312
            if(repository.getJSONArray("datasourceInfo").length() == 0)
313
                return aggregationByYear;
314

    
315
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
316
            return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory);
317

    
318
        } catch (JSONException e) {
319
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
320
            emailUtils.reportException(e);
321
            throw e;
322
        }
323
    }
324

    
325
    private Map<String,List<AggregationDetails>> createYearMap(List<AggregationDetails> aggregationHistory) {
326
        Map<String, List<AggregationDetails>> aggregationByYear;
327
        aggregationHistory = aggregationHistory.stream()
328
                            .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
329
                            .collect(Collectors.toList());
330

    
331
       return aggregationHistory.stream()
332
                            .collect(Collectors.groupingBy(AggregationDetails::getYear));
333
    }
334

    
335

    
336
    @Override
337
    public List<Repository> getRepositoriesByName(@PathVariable("name") String name,
338
                                                  @PathVariable("page") String page,
339
                                                  @PathVariable("size") String size) throws JSONException {
340

    
341
        LOGGER.debug("Retreiving  repositories with official name : " + name );
342
        UriComponents uriComponents = searchDatasource("0","100");
343
        RequestFilter requestFilter = new RequestFilter();
344
        requestFilter.setOfficialname(name);
345

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

    
358
    }
359

    
360
    @Override
361
    public List<RepositoryInterface> getRepositoryInterface(@PathVariable("id") String id) throws JSONException {
362

    
363
        UriComponents uriComponents = UriComponentsBuilder
364
                .fromHttpUrl(baseAddress + "/ds/api/")
365
                .path("/{id}")
366
                .build().expand(id).encode();
367

    
368
        try{
369
            String rs = restTemplate.getForObject(uriComponents.toUri(), String.class);
370
            return Converter.jsonToRepositoryInterfaceList(new JSONObject(rs));
371
        }catch (Exception e ){
372
            LOGGER.debug("Exception on getRepositoryInterface" , e);
373
            emailUtils.reportException(e);
374
            throw e;
375
        }
376

    
377
    }
378

    
379
    @Override
380
    public Repository addRepository(@RequestParam("datatype") String datatype,
381
                                    @RequestBody Repository repository) throws Exception {
382

    
383
        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
384

    
385
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
386
        repository.setActivationId(UUID.randomUUID().toString());
387
        repository.setCollectedFrom("infrastruct_::openaire");
388

    
389
        if (datatype.equals("journal")) {
390
            repository.setId("openaire____::issn" + repository.getIssn());
391
            repository.setNamespacePrefix("issn" + repository.getIssn());
392
            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
393
        }else if (datatype.equals("aggregator")) {
394
            repository.setId("openaire____::" + com.unboundid.util.Base64.encode(repository.getOfficialName()));
395
            repository.setNamespacePrefix(DigestUtils.md5Hex(repository.getOfficialName()).substring(0,12));
396
            this.storeRepository(repository, SecurityContextHolder.getContext().getAuthentication());
397
        }else {
398
            this.latentUpdate(repository, SecurityContextHolder.getContext().getAuthentication());
399
        }
400

    
401
        return repository;
402
    }
403

    
404
    /* update method acting as add -> send email with registration topic/body*/
405
    private Repository latentUpdate(Repository repository, Authentication authentication) throws Exception {
406
        UriComponents uriComponents = UriComponentsBuilder
407
                .fromHttpUrl(baseAddress + "/ds/update/")
408
                .build()
409
                .encode();
410

    
411
        try {
412
            String json_repository = Converter.repositoryObjectToJson(repository);
413
            LOGGER.debug("JSON to add(update) -> " + json_repository);
414

    
415
//
416
//            // TODO delete these 3 lines
417
//            HttpHeaders temp = new HttpHeaders();
418
//            temp.setContentType(MediaType.APPLICATION_JSON_UTF8);
419

    
420
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
421
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
422

    
423
            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
424
                emailUtils.sendUserRegistrationEmail(repository, authentication);
425
            }else
426
                LOGGER.debug(responseEntity.getBody().toString());
427

    
428
            return repository;
429
        } catch (Exception e) {
430
            LOGGER.debug("Exception on updateRepository" , e);
431
            emailUtils.reportException(e);
432
            throw e;
433
        }
434

    
435

    
436
    }
437

    
438
    @Override
439
    public Repository updateRepository(@RequestBody Repository repository,Authentication authentication) throws Exception {
440
        UriComponents uriComponents = UriComponentsBuilder
441
                .fromHttpUrl(baseAddress + "/ds/update/")
442
                .build()
443
                .encode();
444

    
445
        try {
446
            String json_repository = Converter.repositoryObjectToJson(repository);
447

    
448
            LOGGER.debug("JSON to update -> " + json_repository);
449

    
450
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
451
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity
452
                    , ResponseEntity.class);
453

    
454
            if (responseEntity.getStatusCode().equals(HttpStatus.OK))
455
                emailUtils.sendUserUpdateRepositoryEmail(repository, authentication);
456
            else
457
                LOGGER.debug(responseEntity.getBody().toString());
458

    
459
            return repository;
460
        } catch (Exception e) {
461
            LOGGER.debug("Exception on updateRepository" , e);
462
            emailUtils.reportException(e);
463
            throw e;
464
        }
465
    }
466

    
467
    private void updateInterface(String datatype,RepositoryInterface iFace) {
468
        //TODO call update base url
469
        //((DatasourceManagerService) this.dmService.getService()).updateBaseUrl(repo.getId(), iFace.getId(), iFace.getBaseUrl());
470
        if (!iFace.getAccessSet().isEmpty()) {
471
            LOGGER.debug("set not empty: " + iFace.getAccessSet());
472
            //TODO call update method for access params
473
            // ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "set", iFace.getAccessSet(), false);
474
        } else {
475
            //TODO call deleteAccessParamOrExtraField
476
            //((DatasourceManagerService) this.dmService.getService()).deleteAccessParamOrExtraField(repo.getId(), iFace.getId(), "set");
477
        }
478
        //TODO update content description
479
        //((DatasourceManagerService) this.dmService.getService()).updateContentDescription(repo.getId(), iFace.getId(), "metadata");
480
        if (datatype.equals("re3data")) {
481
            //TODO call update access params
482
            //  ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_datacite", false);
483
            iFace.setAccessFormat("oai_datacite");
484
        } else {
485
            //TODO call update access params
486
            //((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_dc", false);
487
            iFace.setAccessFormat("oai_dc");
488
        }
489

    
490
    }
491

    
492
    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
493

    
494
        Date utilDate = new Date();
495
        Timestamp date = new Timestamp(utilDate.getTime());
496
        repository.setDateOfCollection(date);
497
        repository.setAggregator("OPENAIRE");
498
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
499

    
500
        UriComponents uriComponents = UriComponentsBuilder
501
                .fromHttpUrl(baseAddress + "/ds/add/")
502
                .build()
503
                .encode();
504
        String json_repository = Converter.repositoryObjectToJson(repository);
505
        HttpEntity<String> httpEntity = new HttpEntity <String> (json_repository,httpHeaders);
506
        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
507

    
508
        if(responseEntity.getStatusCode().equals(HttpStatus.OK))
509
            emailUtils.sendUserRegistrationEmail(repository,authentication);
510
        else {
511
            LOGGER.debug(responseEntity.getBody().toString());
512
        }
513
    }
514

    
515
    @Override
516
    public void deleteRepositoryInterface(@RequestParam("id") String id ,
517
                                          @RequestParam("registeredBy") String registeredBy){
518
        UriComponents uriComponents = UriComponentsBuilder
519
                .fromHttpUrl(baseAddress + "/ds/api/")
520
                .path("/{id}")
521
                .build().expand(id).encode();
522
        LOGGER.debug(uriComponents.toUri());
523
        restTemplate.delete(uriComponents.toUri());
524
    }
525

    
526
    @Override
527
    public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype,
528
                                                      @RequestParam("repoId") String repoId,
529
                                                      @RequestParam("registeredBy") String registeredBy,
530
                                                      @RequestBody RepositoryInterface repositoryInterface) throws JSONException,ResourceNotFoundException {
531
        try {
532
            Repository e = this.getRepositoryById(repoId);
533
            repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype);
534
            String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface);
535

    
536
            UriComponents uriComponents = UriComponentsBuilder
537
                    .fromHttpUrl(baseAddress + "/ds/api/add/")
538
                    .build()
539
                    .encode();
540

    
541
            HttpEntity<String> httpEntity = new HttpEntity <String> (json_interface,httpHeaders);
542
            restTemplate.postForObject(uriComponents.toUri(),httpEntity,String.class);
543
            return repositoryInterface;
544

    
545
        } catch (JSONException e) {
546
            LOGGER.debug("Exception on addRepositoryInterface" , e);
547
            emailUtils.reportException(e);
548
            throw e;
549
        }
550
    }
551

    
552
    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
553

    
554
        iFace.setContentDescription("metadata");
555
        iFace.setCompliance("UNKNOWN");
556

    
557
        if (datatype.equals("re3data"))
558
            iFace.setAccessFormat("oai_datacite");
559
        else
560
            iFace.setAccessFormat("oai_dc");
561

    
562

    
563
        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
564
            iFace.setTypology(repo.getDatasourceClass());
565
        else if (datatype.equalsIgnoreCase("journal"))
566
            iFace.setTypology("pubsrepository::journal");
567
        else if (datatype.equalsIgnoreCase("aggregator"))
568
            iFace.setTypology("aggregator::pubsrepository::unknown");
569
        else if (datatype.equalsIgnoreCase("opendoar"))
570
            iFace.setTypology("pubsrepository::unknown");
571
        else if (datatype.equalsIgnoreCase("re3data"))
572
            iFace.setTypology("datarepository::unknown");
573

    
574
        iFace.setRemovable(true);
575
        iFace.setAccessProtocol("oai");
576
        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
577
        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
578
        if (iFace.getAccessSet().isEmpty()) {
579
            LOGGER.debug("set is empty: " + iFace.getAccessSet());
580
            iFace.removeAccessSet();
581
        }
582
        return iFace;
583
    }
584

    
585
    @Override
586
    public List<String> getDnetCountries() {
587
        LOGGER.debug("Getting dnet-countries!");
588
        return Converter.readFile("countries.txt");
589
    }
590

    
591
    @Override
592
    public List<String> getTypologies() {
593
        return Converter.readFile("typologies.txt");
594
    }
595

    
596
    @Override
597
    public List<Timezone> getTimezones() {
598
        List<String> timezones =  Converter.readFile("timezones.txt");
599
        return Converter.toTimezones(timezones);
600
    }
601

    
602
    @Override
603
    public List<String> getUrlsOfUserRepos(@PathVariable("user_email") String userEmail,
604
                                           @PathVariable("page") String page,
605
                                           @PathVariable("size") String size) throws JSONException {
606
        UriComponents uriComponents = UriComponentsBuilder
607
                .fromHttpUrl(baseAddress + "/api/baseurl/")
608
                .path("/{page}/{size}")
609
                .build().expand(page,size).encode();
610

    
611
        try{
612
            RequestFilter requestFilter = new RequestFilter();
613
            requestFilter.setRegisteredby(userEmail);
614
            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class));
615
        }catch (Exception e){
616
            LOGGER.debug("Exception on addRepositoryInterface" , e);
617
            emailUtils.reportException(e);
618
            throw e;
619
        }
620
    }
621

    
622
    @Override
623
    public List<String> getDatasourceVocabularies(@PathVariable("mode") String mode) {
624

    
625
        List<String> resultSet = new ArrayList<>();
626
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
627
            if (mode.equalsIgnoreCase("aggregator")) {
628
                if (entry.getKey().contains("aggregator"))
629
                    resultSet.add(entry.getValue());
630
            } else if (mode.equalsIgnoreCase("journal")) {
631
                if (entry.getKey().contains("journal"))
632
                    resultSet.add(entry.getValue());
633
            } else if (mode.equalsIgnoreCase("opendoar")) {
634
                if (entry.getKey().contains("pubsrepository"))
635
                    resultSet.add(entry.getValue());
636
            } else if (mode.equalsIgnoreCase("re3data")) {
637
                if (entry.getKey().contains("datarepository"))
638
                    resultSet.add(entry.getValue());
639
            }
640
        }
641

    
642

    
643
        return resultSet;
644
    }
645

    
646
    private Vocabulary getVocabulary(String vocName) {
647

    
648
        if (!vocabularyMap.containsKey(vocName)) {
649
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
650
        }
651
        return vocabularyMap.get(vocName);
652
    }
653

    
654

    
655
    @Override
656
    public Map<String, String> getCompatibilityClasses(@PathVariable("mode") String mode)  {
657

    
658
        LOGGER.debug("Getting compatibility classes for mode: " + mode);
659
        Map<String, String> retMap = new HashMap<String, String>();
660

    
661
        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
662
        boolean foundData = false;
663
        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
664
            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
665
                return compatibilityClasses;
666
            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
667
                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
668
                    retMap.put(entry.getKey(), entry.getValue());
669
                    foundData = true;
670
                }
671
            } else {
672
                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
673
                    retMap.put(entry.getKey(), entry.getValue());
674
            }
675
        }
676

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

    
681
        return retMap;
682
    }
683

    
684
    @Override
685
    public Map<String, String> getDatasourceClasses(@PathVariable("mode") String mode)  {
686

    
687
        LOGGER.debug("Getting datasource classes for mode: " + mode);
688

    
689
        Map<String, String> retMap = new HashMap<String, String>();
690

    
691
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
692
            if (mode.equalsIgnoreCase("aggregator")) {
693
                if (entry.getKey().contains("aggregator"))
694
                    retMap.put(entry.getKey(), entry.getValue());
695
            } else if (mode.equalsIgnoreCase("journal")) {
696
                if (entry.getKey().contains("journal"))
697
                    retMap.put(entry.getKey(), entry.getValue());
698
            } else if (mode.equalsIgnoreCase("opendoar")) {
699
                if (entry.getKey().contains("pubsrepository"))
700
                    retMap.put(entry.getKey(), entry.getValue());
701
            } else if (mode.equalsIgnoreCase("re3data")) {
702
                if (entry.getKey().contains("datarepository"))
703
                    retMap.put(entry.getKey(), entry.getValue());
704
            }
705
        }
706
        return filterResults(retMap,mode);
707

    
708
    }
709

    
710
    private Map<String,String> filterResults(Map<String, String> map,String mode) {
711

    
712
        HashMap<String,String> filteredMap = new HashMap<>();
713
        for(String key:map.keySet())
714
            if(dataSourceClass.get(mode).contains(key))
715
                filteredMap.put(key,map.get(key));
716

    
717
        return filteredMap;
718
    }
719

    
720
    @Override
721
    public String getCountryName(String countryCode) {
722
        return inverseCountriesMap.get(countryCode);
723
    }
724

    
725
    @Override
726
    public MetricsInfo getMetricsInfoForRepository(@PathVariable("repoId")  String repoId) throws RepositoryServiceException {
727
        try {
728

    
729
            MetricsInfo metricsInfo = new MetricsInfo();
730
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
731
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
732
            return metricsInfo;
733

    
734
        } catch (Exception e) {
735
            LOGGER.error("Error while getting metrics info for repository: ", e);
736
            emailUtils.reportException(e);
737
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
738
        }
739
    }
740

    
741
    @Override
742
    public Map<String, String> getListLatestUpdate(@PathVariable("mode")  String mode) throws JSONException {
743
        if(mode.equals("opendoar"))
744
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate());
745
        else
746
            /*
747
            * first api of re3data has null value on collection date
748
            * */
749
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
750
    }
751

    
752
    @Override
753
    public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
754
                                                         @RequestParam("registeredBy") String registeredBy,
755
                                                         @RequestBody RepositoryInterface repositoryInterface) throws Exception {
756

    
757
        this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl());
758
        this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance());
759
        this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet());
760
        return repositoryInterface;
761
    }
762

    
763
    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
764
        UriComponents uriComponents = UriComponentsBuilder
765
                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
766
                .queryParam("dsId",repositoryId)
767
                .queryParam("apiId",repositoryInterfaceId)
768
                .queryParam("oaiSet",validationSet)
769
                .build().encode();
770
       restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, null, ResponseEntity.class);
771

    
772
    }
773

    
774

    
775
    private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) {
776
        UriComponents uriComponents = UriComponentsBuilder
777
                .fromHttpUrl(baseAddress + "/ds/api/baseurl")
778
                .queryParam("dsId",repositoryId)
779
                .queryParam("apiId",repositoryInterfaceId)
780
                .queryParam("baseUrl",baseUrl)
781
                .build().encode();
782
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
783
    }
784

    
785
    private void updateCompliance(String repositoryId, String repositoryInterfaceId,String compliance) {
786
        UriComponents uriComponents = UriComponentsBuilder
787
                .fromHttpUrl(baseAddress + "/ds/api/compliance")
788
                .queryParam("dsId",repositoryId)
789
                .queryParam("apiId",repositoryInterfaceId)
790
                .queryParam("compliance",compliance)
791
                .build().encode();
792
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
793
    }
794

    
795
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
796

    
797
        //build the uri params
798
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
799

    
800
        //create new template engine
801
        RestTemplate template = new RestTemplate();
802
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
803
        ResponseEntity<MetricsNumbers> resp;
804
        try {
805
            //communicate with endpoint
806
            resp = template.exchange(
807
                    builder.build().encode().toUri(),
808
                    HttpMethod.GET,
809
                    null,
810
                    new ParameterizedTypeReference<MetricsNumbers>() {
811
                    });
812
        } catch (RestClientException e) {
813
            LOGGER.debug("Exception on getMetricsNumbers" , e);
814
            emailUtils.reportException(e);
815
            throw e;
816
        }
817

    
818
        return resp.getBody();
819
    }
820

    
821
    private String getOpenAIREId(String repoId) {
822

    
823
        if (repoId != null && repoId.contains("::")) {
824
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
825
        }
826

    
827
        return null;
828
    }
829

    
830
    private UriComponents searchDatasource(String page,String size){
831

    
832
        return UriComponentsBuilder
833
                .fromHttpUrl(baseAddress + "/ds/search/")
834
                .path("/{page}/{size}/")
835
                .queryParam("requestSortBy","officialname")
836
                .queryParam("order","ASCENDING")
837
                .build().expand(page, size).encode();
838
    }
839

    
840
    private UriComponents searchSnipperDatasource(String page,String size){
841

    
842
        return UriComponentsBuilder
843
                .fromHttpUrl(baseAddress + "/ds/searchsnippet/")
844
                .path("/{page}/{size}/")
845
                .queryParam("requestSortBy","officialname")
846
                .queryParam("order","ASCENDING")
847
                .build().expand(page, size).encode();
848
    }
849

    
850
    private String getRepositoryType(String typology){
851
        return invertedDataSourceClass.get(typology);
852
    }
853

    
854

    
855
}
(10-10/18)