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

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

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

    
131

    
132
    }
133

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

    
142

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

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

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

    
160

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

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

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

    
187

    
188
    }
189

    
190
    private Repository updateRepositoryInfo(Repository r) throws JSONException {
191

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

    
203

    
204
    private Collection<Repository> getRepositoriesByMode(String mode, List<Repository> rs) {
205

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

    
211
        }
212
        return reps;
213
    }
214

    
215
    @Override
216
    public List<Repository> getRepositoriesOfUser(@PathVariable("userEmail") String userEmail,
217
                                                  @PathVariable("page") String page,
218
                                                  @PathVariable("size") String size) throws JSONException {
219

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

    
225
        try{
226
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
227

    
228
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
229
            for (Repository r : repos)
230
                this.updateRepositoryInfo(r);
231

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

    
240
    @Override
241
    public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException,ResourceNotFoundException {
242

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

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

    
253
            if(jsonArray.length() == 0)
254
                throw new ResourceNotFoundException();
255

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

    
264
    }
265

    
266

    
267
    @Override
268
    public List<AggregationDetails> getRepositoryAggregations(@PathVariable("id") String id) throws JSONException {
269

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

    
275
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
276

    
277
        try {
278
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
279
            JSONObject repository = new JSONObject(rs);
280

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

    
294
    }
295

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

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

    
309
            if(repository.getJSONArray("datasourceInfo").length() == 0)
310
                return aggregationByYear;
311

    
312
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
313
            return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory);
314

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

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

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

    
332

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

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

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

    
355
    }
356

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

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

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

    
374
    }
375

    
376
    @Override
377
    public Repository addRepository(@RequestParam("datatype") String datatype,
378
                                    @RequestBody Repository repository) throws Exception {
379

    
380
        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
381

    
382
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
383
        repository.setActivationId(UUID.randomUUID().toString());
384
        repository.setCollectedFrom("infrastruct_::openaire");
385

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

    
398
        return repository;
399
    }
400

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

    
408
        try {
409
            String json_repository = Converter.repositoryObjectToJson(repository);
410
            LOGGER.debug("JSON to add(update) -> " + json_repository);
411

    
412
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
413
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
414

    
415
            if (responseEntity.getStatusCode().equals(HttpStatus.OK)) {
416
                emailUtils.sendUserRegistrationEmail(repository, authentication);
417
            }else
418
                LOGGER.debug(responseEntity.getBody().toString());
419

    
420
            return repository;
421
        } catch (Exception e) {
422
            LOGGER.debug("Exception on updateRepository" , e);
423
            emailUtils.reportException(e);
424
            throw e;
425
        }
426

    
427

    
428
    }
429

    
430
    @Override
431
    public Repository updateRepository(@RequestBody Repository repository,Authentication authentication) throws Exception {
432
        UriComponents uriComponents = UriComponentsBuilder
433
                .fromHttpUrl(baseAddress + "/ds/update/")
434
                .build()
435
                .encode();
436

    
437
        try {
438
            String json_repository = Converter.repositoryObjectToJson(repository);
439

    
440
            LOGGER.debug("JSON to update -> " + json_repository);
441

    
442
            HttpEntity<String> httpEntity = new HttpEntity<String>(json_repository, httpHeaders);
443
            ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
444

    
445
            if (responseEntity.getStatusCode().equals(HttpStatus.OK))
446
                emailUtils.sendUserUpdateRepositoryEmail(repository, authentication);
447
            else
448
                LOGGER.debug(responseEntity.getBody().toString());
449

    
450
            return repository;
451
        } catch (Exception e) {
452
            LOGGER.debug("Exception on updateRepository" , e);
453
            emailUtils.reportException(e);
454
            throw e;
455
        }
456
    }
457

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

    
481
    }
482

    
483
    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
484

    
485
        Date utilDate = new Date();
486
        Timestamp date = new Timestamp(utilDate.getTime());
487
        repository.setDateOfCollection(date);
488
        repository.setAggregator("OPENAIRE");
489
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
490

    
491
        UriComponents uriComponents = UriComponentsBuilder
492
                .fromHttpUrl(baseAddress + "/ds/add/")
493
                .build()
494
                .encode();
495
        String json_repository = Converter.repositoryObjectToJson(repository);
496
        HttpEntity<String> httpEntity = new HttpEntity <String> (json_repository,httpHeaders);
497
        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
498

    
499
        if(responseEntity.getStatusCode().equals(HttpStatus.OK))
500
            emailUtils.sendUserRegistrationEmail(repository,authentication);
501
        else {
502
            LOGGER.debug(responseEntity.getBody().toString());
503
        }
504
    }
505

    
506
    @Override
507
    public void deleteRepositoryInterface(@RequestParam("id") String id ,
508
                                          @RequestParam("registeredBy") String registeredBy){
509
        UriComponents uriComponents = UriComponentsBuilder
510
                .fromHttpUrl(baseAddress + "/ds/api/")
511
                .path("/{id}")
512
                .build().expand(id).encode();
513
        LOGGER.debug(uriComponents.toUri());
514
        restTemplate.delete(uriComponents.toUri());
515
    }
516

    
517
    @Override
518
    public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype,
519
                                                      @RequestParam("repoId") String repoId,
520
                                                      @RequestParam("registeredBy") String registeredBy,
521
                                                      @RequestBody RepositoryInterface repositoryInterface) throws JSONException,ResourceNotFoundException {
522
        try {
523
            Repository e = this.getRepositoryById(repoId);
524
            repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype);
525
            String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface);
526

    
527
            UriComponents uriComponents = UriComponentsBuilder
528
                    .fromHttpUrl(baseAddress + "/ds/api/add/")
529
                    .build()
530
                    .encode();
531

    
532
            HttpEntity<String> httpEntity = new HttpEntity <String> (json_interface,httpHeaders);
533
            restTemplate.postForObject(uriComponents.toUri(),httpEntity,String.class);
534
            return repositoryInterface;
535

    
536
        } catch (JSONException e) {
537
            LOGGER.debug("Exception on addRepositoryInterface" , e);
538
            emailUtils.reportException(e);
539
            throw e;
540
        }
541
    }
542

    
543
    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
544

    
545
        iFace.setContentDescription("metadata");
546
        iFace.setCompliance("UNKNOWN");
547

    
548
        if (datatype.equals("re3data"))
549
            iFace.setAccessFormat("oai_datacite");
550
        else
551
            iFace.setAccessFormat("oai_dc");
552

    
553

    
554
        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
555
            iFace.setTypology(repo.getDatasourceClass());
556
        else if (datatype.equalsIgnoreCase("journal"))
557
            iFace.setTypology("pubsrepository::journal");
558
        else if (datatype.equalsIgnoreCase("aggregator"))
559
            iFace.setTypology("aggregator::pubsrepository::unknown");
560
        else if (datatype.equalsIgnoreCase("opendoar"))
561
            iFace.setTypology("pubsrepository::unknown");
562
        else if (datatype.equalsIgnoreCase("re3data"))
563
            iFace.setTypology("datarepository::unknown");
564

    
565
        iFace.setRemovable(true);
566
        iFace.setAccessProtocol("oai");
567
        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
568
        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
569
        if (iFace.getAccessSet().isEmpty()) {
570
            LOGGER.debug("set is empty: " + iFace.getAccessSet());
571
            iFace.removeAccessSet();
572
        }
573
        return iFace;
574
    }
575

    
576
    @Override
577
    public List<String> getDnetCountries() {
578
        LOGGER.debug("Getting dnet-countries!");
579
        return Converter.readFile("countries.txt");
580
    }
581

    
582
    @Override
583
    public List<String> getTypologies() {
584
        return Converter.readFile("typologies.txt");
585
    }
586

    
587
    @Override
588
    public List<Timezone> getTimezones() {
589
        List<String> timezones =  Converter.readFile("timezones.txt");
590
        return Converter.toTimezones(timezones);
591
    }
592

    
593
    @Override
594
    public List<String> getUrlsOfUserRepos(@PathVariable("user_email") String userEmail,
595
                                           @PathVariable("page") String page,
596
                                           @PathVariable("size") String size) throws JSONException {
597
        UriComponents uriComponents = UriComponentsBuilder
598
                .fromHttpUrl(baseAddress + "/api/baseurl/")
599
                .path("/{page}/{size}")
600
                .build().expand(page,size).encode();
601

    
602
        try{
603
            RequestFilter requestFilter = new RequestFilter();
604
            requestFilter.setRegisteredby(userEmail);
605
            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class));
606
        }catch (Exception e){
607
            LOGGER.debug("Exception on addRepositoryInterface" , e);
608
            emailUtils.reportException(e);
609
            throw e;
610
        }
611
    }
612

    
613
    @Override
614
    public List<String> getDatasourceVocabularies(@PathVariable("mode") String mode) {
615

    
616
        List<String> resultSet = new ArrayList<>();
617
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
618
            if (mode.equalsIgnoreCase("aggregator")) {
619
                if (entry.getKey().contains("aggregator"))
620
                    resultSet.add(entry.getValue());
621
            } else if (mode.equalsIgnoreCase("journal")) {
622
                if (entry.getKey().contains("journal"))
623
                    resultSet.add(entry.getValue());
624
            } else if (mode.equalsIgnoreCase("opendoar")) {
625
                if (entry.getKey().contains("pubsrepository"))
626
                    resultSet.add(entry.getValue());
627
            } else if (mode.equalsIgnoreCase("re3data")) {
628
                if (entry.getKey().contains("datarepository"))
629
                    resultSet.add(entry.getValue());
630
            }
631
        }
632

    
633

    
634
        return resultSet;
635
    }
636

    
637
    private Vocabulary getVocabulary(String vocName) {
638

    
639
        if (!vocabularyMap.containsKey(vocName)) {
640
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
641
        }
642
        return vocabularyMap.get(vocName);
643
    }
644

    
645

    
646
    @Override
647
    public Map<String, String> getCompatibilityClasses(@PathVariable("mode") String mode)  {
648

    
649
        LOGGER.debug("Getting compatibility classes for mode: " + mode);
650
        Map<String, String> retMap = new HashMap<String, String>();
651

    
652
        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
653
        boolean foundData = false;
654
        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
655
            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
656
                return compatibilityClasses;
657
            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
658
                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
659
                    retMap.put(entry.getKey(), entry.getValue());
660
                    foundData = true;
661
                }
662
            } else {
663
                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
664
                    retMap.put(entry.getKey(), entry.getValue());
665
            }
666
        }
667

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

    
672
        return retMap;
673
    }
674

    
675
    @Override
676
    public Map<String, String> getDatasourceClasses(@PathVariable("mode") String mode)  {
677

    
678
        LOGGER.debug("Getting datasource classes for mode: " + mode);
679

    
680
        Map<String, String> retMap = new HashMap<String, String>();
681

    
682
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
683
            if (mode.equalsIgnoreCase("aggregator")) {
684
                if (entry.getKey().contains("aggregator"))
685
                    retMap.put(entry.getKey(), entry.getValue());
686
            } else if (mode.equalsIgnoreCase("journal")) {
687
                if (entry.getKey().contains("journal"))
688
                    retMap.put(entry.getKey(), entry.getValue());
689
            } else if (mode.equalsIgnoreCase("opendoar")) {
690
                if (entry.getKey().contains("pubsrepository"))
691
                    retMap.put(entry.getKey(), entry.getValue());
692
            } else if (mode.equalsIgnoreCase("re3data")) {
693
                if (entry.getKey().contains("datarepository"))
694
                    retMap.put(entry.getKey(), entry.getValue());
695
            }
696
        }
697
        return filterResults(retMap,mode);
698

    
699
    }
700

    
701
    private Map<String,String> filterResults(Map<String, String> map,String mode) {
702

    
703
        HashMap<String,String> filteredMap = new HashMap<>();
704
        for(String key:map.keySet())
705
            if(dataSourceClass.get(mode).contains(key))
706
                filteredMap.put(key,map.get(key));
707

    
708
        return filteredMap;
709
    }
710

    
711
    @Override
712
    public String getCountryName(String countryCode) {
713
        return inverseCountriesMap.get(countryCode);
714
    }
715

    
716
    @Override
717
    public MetricsInfo getMetricsInfoForRepository(@PathVariable("repoId")  String repoId) throws RepositoryServiceException {
718
        try {
719

    
720
            MetricsInfo metricsInfo = new MetricsInfo();
721
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
722
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
723
            return metricsInfo;
724

    
725
        } catch (Exception e) {
726
            LOGGER.error("Error while getting metrics info for repository: ", e);
727
            emailUtils.reportException(e);
728
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
729
        }
730
    }
731

    
732
    @Override
733
    public Map<String, String> getListLatestUpdate(@PathVariable("mode")  String mode) throws JSONException {
734
        if(mode.equals("opendoar"))
735
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate());
736
        else
737
            /*
738
            * first api of re3data has null value on collection date
739
            * */
740
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
741
    }
742

    
743
    @Override
744
    public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
745
                                                         @RequestParam("registeredBy") String registeredBy,
746
                                                         @RequestBody RepositoryInterface repositoryInterface) throws Exception {
747

    
748
        this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl());
749
        this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance());
750
        this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet());
751
        return repositoryInterface;
752
    }
753

    
754
    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
755
        UriComponents uriComponents = UriComponentsBuilder
756
                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
757
                .queryParam("dsId",repositoryId)
758
                .queryParam("apiId",repositoryInterfaceId)
759
                .queryParam("oaiSet",validationSet)
760
                .build().encode();
761
       restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, null, ResponseEntity.class);
762

    
763
    }
764

    
765

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

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

    
786
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
787

    
788
        //build the uri params
789
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
790

    
791
        //create new template engine
792
        RestTemplate template = new RestTemplate();
793
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
794
        ResponseEntity<MetricsNumbers> resp;
795
        try {
796
            //communicate with endpoint
797
            resp = template.exchange(
798
                    builder.build().encode().toUri(),
799
                    HttpMethod.GET,
800
                    null,
801
                    new ParameterizedTypeReference<MetricsNumbers>() {
802
                    });
803
        } catch (RestClientException e) {
804
            LOGGER.debug("Exception on getMetricsNumbers" , e);
805
            emailUtils.reportException(e);
806
            throw e;
807
        }
808

    
809
        return resp.getBody();
810
    }
811

    
812
    private String getOpenAIREId(String repoId) {
813

    
814
        if (repoId != null && repoId.contains("::")) {
815
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
816
        }
817

    
818
        return null;
819
    }
820

    
821
    private UriComponents searchDatasource(String page,String size){
822

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

    
831
    private UriComponents searchSnipperDatasource(String page,String size){
832

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

    
841
    private String getRepositoryType(String typology){
842
        return invertedDataSourceClass.get(typology);
843
    }
844

    
845

    
846
}
(10-10/18)