Project

General

Profile

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

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

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

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

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

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

    
55
    @Autowired
56
    RestTemplate restTemplate;
57

    
58
    private HttpHeaders httpHeaders;
59

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

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

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

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

    
70
    @Autowired
71
    private VocabularyLoader vocabularyLoader;
72

    
73
    @Autowired
74
    private PiWikService piWikService;
75

    
76
    @Autowired
77
    private EmailUtils emailUtils;
78

    
79
    @Autowired
80
    ValidatorService validatorService;
81

    
82

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

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

    
88
    private static Map<String,List<String>> dataSourceClass = new HashMap<String,List<String>>(){{
89
        put("opendoar",new ArrayList<String>(){{ add("pubsrepository::institutional");
90
                                                    add("pubsrepository::thematic");
91
                                                    add("pubsrepository::unknown");
92
                                                    add("pubsrepository::mock");
93
        }});
94
        put("re3data",new ArrayList<String>(){{ add("datarepository::unknown");
95
        }});
96
        put("journal",new ArrayList<String>(){{ add("pubsrepository::journal");
97
        }});
98
        put("aggregator",new ArrayList<String>(){{ add("aggregator::pubsrepository::institutional");
99
                                                        add("aggregator::pubsrepository::journals");
100
                                                        add("aggregator::datarepository");
101
                                                        add("aggregator::pubsrepository::unknown");
102
        }});
103
    }};
104

    
105
    private static Map<String,String> invertedDataSourceClass = new HashMap<String,String>(){{
106
        put("pubsrepository::institutional","opendoar");
107
        put("pubsrepository::thematic","opendoar");
108
        put("pubsrepository::unknown","opendoar");
109
        put("pubsrepository::mock","opendoar");
110

    
111
        put("datarepository::unknown","re3data");
112

    
113
        put("pubsrepository::journal","journal");
114

    
115
        put("aggregator::pubsrepository::institutional","aggregator");
116
        put("aggregator::pubsrepository::journals","aggregator");
117
        put("aggregator::datarepository","aggregator");
118
        put("aggregator::pubsrepository::unknown","aggregator");
119

    
120
    }};
121

    
122

    
123

    
124
    @PostConstruct
125
    private void init() {
126
        LOGGER.debug("Initialization method of repository api!");
127
        LOGGER.debug("Updated version!");
128

    
129
        httpHeaders = new HttpHeaders();
130
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
131

    
132
        for (String vocName : vocabularyNames) {
133
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
134
        }
135

    
136
        Country[] countries = getCountries();
137
        for (Country c : countries) {
138
            countriesMap.put(c.getName(), c.getCode());
139
            inverseCountriesMap.put(c.getCode(), c.getName());
140
        }
141

    
142

    
143
    }
144

    
145
    @Override
146
    public Country[] getCountries() {
147
        UriComponents uriComponents = UriComponentsBuilder
148
                .fromHttpUrl(baseAddress + "/ds/countries")
149
                .build().encode();
150
        return restTemplate.getForObject(uriComponents.toUri(), Country[].class);
151
    }
152

    
153

    
154
    @Override
155
    public List<RepositorySnippet> getRepositoriesByCountry(@PathVariable("country") String country,
156
                                                            @PathVariable("mode") String mode,
157
                                                            @RequestParam(value = "managed",required=false) Boolean managed) throws JSONException, IOException {
158

    
159
        LOGGER.debug("Getting repositories by country!");
160
        int page = 0;
161
        int size = 100;
162
        List<RepositorySnippet> resultSet = new ArrayList<>();
163
        ObjectMapper mapper = new ObjectMapper();
164

    
165
        String filterKey = "UNKNOWN";
166
        if (mode.equalsIgnoreCase("opendoar"))
167
            filterKey = "openaire____::opendoar";
168
        else if (mode.equalsIgnoreCase("re3data"))
169
            filterKey = "openaire____::re3data";
170

    
171

    
172
        LOGGER.debug("Country code equals : " + country);
173
        LOGGER.debug("Filter mode equals : " + filterKey);
174

    
175
        UriComponents uriComponents = searchSnipperDatasource(String.valueOf(page),String.valueOf(size));
176
        RequestFilter requestFilter = new RequestFilter();
177
        requestFilter.setCountry(country);
178
        requestFilter.setCollectedfrom(filterKey);
179

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

    
199
    public List<RepositorySnippet> searchRegisteredRepositories(String country, String typology, String englishName,
200
            String officialName, String requestSortBy, String order, int page, int pageSize) throws Exception {
201

    
202
        LOGGER.debug("Searching registered repositories");
203

    
204
        List<RepositorySnippet> resultSet = new ArrayList<>();
205
        ObjectMapper mapper = new ObjectMapper();
206

    
207
        UriComponents uriComponents = searchRegisteredDatasource(requestSortBy, order, Integer.toString(page), Integer.toString(pageSize));
208

    
209
        RequestFilter requestFilter = new RequestFilter();
210
        requestFilter.setCountry(country);
211
        requestFilter.setTypology(typology);
212
        requestFilter.setOfficialname(officialName);
213
        requestFilter.setEnglishname(englishName);
214

    
215
        try {
216
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
217
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
218

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

    
221
             return resultSet;
222
        }catch (Exception e){
223
            LOGGER.error("Error searching registered datasources" , e);
224
            throw e;
225
        }
226
    }
227

    
228
    private Repository updateRepositoryInfo(Repository r) throws JSONException {
229

    
230
        /*
231
        * from datasource class
232
        * we get the datasource type form the inverted map
233
        * */
234
        r.setDatasourceType(getRepositoryType(r.getDatasourceClass()));
235
        r.setInterfaces(this.getRepositoryInterface(r.getId()));
236
        r.setPiwikInfo(piWikService.getPiwikSiteForRepo(r.getId()));
237
        r.setCountryName(getCountryName(r.getCountryCode()));
238
        return r;
239
    }
240

    
241

    
242
    private Collection<Repository> getRepositoriesByMode(String mode, List<Repository> rs) {
243

    
244
        List<Repository> reps = new ArrayList<>();
245
        for (Repository r : rs) {
246
            if (r.getCollectedFrom() != null && r.getCollectedFrom().equals(mode))
247
                reps.add(r);
248

    
249
        }
250
        return reps;
251
    }
252

    
253
    @Override
254
    public List<Repository> getRepositoriesOfUser(@PathVariable("userEmail") String userEmail,
255
                                                  @PathVariable("page") String page,
256
                                                  @PathVariable("size") String size) throws JSONException {
257

    
258
        LOGGER.debug("Retreiving repositories of user : " + userEmail );
259
        UriComponents uriComponents = searchDatasource(page,size);
260
        RequestFilter requestFilter = new RequestFilter();
261
        requestFilter.setRegisteredby(userEmail);
262

    
263
        try{
264
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
265

    
266
            List<Repository> repos = Converter.jsonToRepositoryList(new JSONObject(rs));
267
            for (Repository r : repos)
268
                this.updateRepositoryInfo(r);
269

    
270
            return repos;
271
        }catch (Exception e){
272
            LOGGER.debug("Exception on getRepositoriesOfUser" , e);
273
            emailUtils.reportException(e);
274
            throw e;
275
        }
276
    }
277

    
278
    @Override
279
    public Repository getRepositoryById(@PathVariable("id") String id) throws JSONException,ResourceNotFoundException {
280

    
281
        LOGGER.debug("Retreiving repositories with id : " + id );
282
        Repository repo = null;
283
        UriComponents uriComponents = searchDatasource("0","100");
284
        RequestFilter requestFilter = new RequestFilter();
285
        requestFilter.setId(id);
286

    
287
        try{
288
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
289
            JSONArray jsonArray = (JSONArray) new JSONObject(rs).get("datasourceInfo");
290

    
291
            if(jsonArray.length() == 0)
292
                throw new ResourceNotFoundException();
293

    
294
            repo = Converter.jsonToRepositoryObject(jsonArray.getJSONObject(0));
295
            return updateRepositoryInfo(repo);
296
        }catch (JSONException e){
297
            LOGGER.debug("Exception on getRepositoryById" , e);
298
            emailUtils.reportException(e);
299
            throw e;
300
        }
301

    
302
    }
303

    
304

    
305
    @Override
306
    public List<AggregationDetails> getRepositoryAggregations(@PathVariable("id") String id) throws JSONException {
307

    
308
        LOGGER.debug("Retreiving aggregations for repository with id : " + id );
309
        UriComponents uriComponents = searchDatasource("0","100");
310
        RequestFilter requestFilter = new RequestFilter();
311
        requestFilter.setId(id);
312

    
313
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
314

    
315
        try {
316
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
317
            JSONObject repository = new JSONObject(rs);
318

    
319
            if(repository.getJSONArray("datasourceInfo").length() == 0)
320
                return aggregationHistory;
321
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
322
            return aggregationHistory.size() == 0? aggregationHistory : aggregationHistory.stream()
323
                                                    .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
324
                                                    .limit(20)
325
                                                    .collect(Collectors.toList());
326
        } catch (JSONException e) {
327
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
328
            emailUtils.reportException(e);
329
            throw e;
330
        }
331

    
332
    }
333

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

    
341
        List<AggregationDetails> aggregationHistory = new ArrayList<>();
342
        Map<String, List<AggregationDetails>> aggregationByYear = new HashMap<>();
343
        try {
344
            String rs = restTemplate.postForObject(uriComponents.toUri(),requestFilter, String.class);
345
            JSONObject repository = new JSONObject(rs);
346

    
347
            if(repository.getJSONArray("datasourceInfo").length() == 0)
348
                return aggregationByYear;
349

    
350
            aggregationHistory.addAll(Converter.getAggregationHistoryFromJson(repository.getJSONArray("datasourceInfo").getJSONObject(0)));
351
            return aggregationHistory.size() == 0? aggregationByYear:createYearMap(aggregationHistory);
352

    
353
        } catch (JSONException e) {
354
            LOGGER.debug("Exception on getRepositoryAggregations" , e);
355
            emailUtils.reportException(e);
356
            throw e;
357
        }
358
    }
359

    
360
    private Map<String,List<AggregationDetails>> createYearMap(List<AggregationDetails> aggregationHistory) {
361
        Map<String, List<AggregationDetails>> aggregationByYear;
362
        aggregationHistory = aggregationHistory.stream()
363
                            .sorted(Comparator.comparing(AggregationDetails::getDate).reversed())
364
                            .collect(Collectors.toList());
365

    
366
       return aggregationHistory.stream()
367
                            .collect(Collectors.groupingBy(AggregationDetails::getYear));
368
    }
369

    
370

    
371
    @Override
372
    public List<Repository> getRepositoriesByName(@PathVariable("name") String name,
373
                                                  @PathVariable("page") String page,
374
                                                  @PathVariable("size") String size) throws JSONException {
375

    
376
        LOGGER.debug("Retreiving  repositories with official name : " + name );
377
        UriComponents uriComponents = searchDatasource("0","100");
378
        RequestFilter requestFilter = new RequestFilter();
379
        requestFilter.setOfficialname(name);
380

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

    
393
    }
394

    
395
    @Override
396
    public List<RepositoryInterface> getRepositoryInterface(@PathVariable("id") String id) throws JSONException {
397

    
398
        UriComponents uriComponents = UriComponentsBuilder
399
                .fromHttpUrl(baseAddress + "/ds/api/")
400
                .path("/{id}")
401
                .build().expand(id).encode();
402

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

    
412
    }
413

    
414
    @Override
415
    public Repository addRepository(@RequestParam("datatype") String datatype,
416
                                    @RequestBody Repository repository) throws Exception {
417

    
418
        LOGGER.debug("storing " + datatype + " repository with id: " + repository.getId());
419

    
420
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
421
        repository.setActivationId(UUID.randomUUID().toString());
422
        repository.setCollectedFrom("infrastruct_::openaire");
423

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

    
436
        return repository;
437
    }
438

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

    
446
        try {
447
            String json_repository = Converter.repositoryObjectToJson(repository);
448
            LOGGER.debug("JSON to add(update) -> " + json_repository);
449

    
450
//
451
//            // TODO delete these 3 lines
452
//            HttpHeaders temp = new HttpHeaders();
453
//            temp.setContentType(MediaType.APPLICATION_JSON_UTF8);
454

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

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

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

    
471

    
472
    }
473

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

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

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

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

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

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

    
504
    private void updateInterface(String datatype,RepositoryInterface iFace) {
505
        //TODO call update base url
506
        //((DatasourceManagerService) this.dmService.getService()).updateBaseUrl(repo.getId(), iFace.getId(), iFace.getBaseUrl());
507
        if (!iFace.getAccessSet().isEmpty()) {
508
            LOGGER.debug("set not empty: " + iFace.getAccessSet());
509
            //TODO call update method for access params
510
            // ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "set", iFace.getAccessSet(), false);
511
        } else {
512
            //TODO call deleteAccessParamOrExtraField
513
            //((DatasourceManagerService) this.dmService.getService()).deleteAccessParamOrExtraField(repo.getId(), iFace.getId(), "set");
514
        }
515
        //TODO update content description
516
        //((DatasourceManagerService) this.dmService.getService()).updateContentDescription(repo.getId(), iFace.getId(), "metadata");
517
        if (datatype.equals("re3data")) {
518
            //TODO call update access params
519
            //  ((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_datacite", false);
520
            iFace.setAccessFormat("oai_datacite");
521
        } else {
522
            //TODO call update access params
523
            //((DatasourceManagerService) this.dmService.getService()).updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_dc", false);
524
            iFace.setAccessFormat("oai_dc");
525
        }
526

    
527
    }
528

    
529
    private void storeRepository(Repository repository, Authentication authentication) throws Exception {
530

    
531
        Date utilDate = new Date();
532
        Timestamp date = new Timestamp(utilDate.getTime());
533
        repository.setDateOfCollection(date);
534
        repository.setAggregator("OPENAIRE");
535
        repository.setCountryCode(countriesMap.get(repository.getCountryName()));
536

    
537
        UriComponents uriComponents = UriComponentsBuilder
538
                .fromHttpUrl(baseAddress + "/ds/add/")
539
                .build()
540
                .encode();
541
        String json_repository = Converter.repositoryObjectToJson(repository);
542
        HttpEntity<String> httpEntity = new HttpEntity <String> (json_repository,httpHeaders);
543
        ResponseEntity responseEntity = restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, httpEntity, ResponseEntity.class);
544

    
545
        if(responseEntity.getStatusCode().equals(HttpStatus.OK)) {
546
            emailUtils.sendUserRegistrationEmail(repository, authentication);
547
            emailUtils.sendAdminRegistrationEmail(repository, authentication);
548
        } else {
549
            LOGGER.debug(responseEntity.getBody().toString());
550
        }
551
    }
552

    
553
    @Override
554
    public void deleteRepositoryInterface(@RequestParam("id") String id ,
555
                                          @RequestParam("registeredBy") String registeredBy){
556
        UriComponents uriComponents = UriComponentsBuilder
557
                .fromHttpUrl(baseAddress + "/ds/api/")
558
                .path("/{id}")
559
                .build().expand(id).encode();
560
        LOGGER.debug(uriComponents.toUri());
561
        restTemplate.delete(uriComponents.toUri());
562
    }
563

    
564
    @Override
565
    public RepositoryInterface addRepositoryInterface(@RequestParam("datatype") String datatype,
566
                                                      @RequestParam("repoId") String repoId,
567
                                                      @RequestParam("registeredBy") String registeredBy,
568
                                                      @RequestBody RepositoryInterface repositoryInterface) throws JSONException,ResourceNotFoundException {
569
        try {
570
            Repository e = this.getRepositoryById(repoId);
571
            repositoryInterface = createRepositoryInterface(e,repositoryInterface,datatype);
572
            String json_interface = Converter.repositoryInterfaceObjectToJson(e,repositoryInterface);
573

    
574
            UriComponents uriComponents = UriComponentsBuilder
575
                    .fromHttpUrl(baseAddress + "/ds/api/add/")
576
                    .build()
577
                    .encode();
578

    
579
            HttpEntity<String> httpEntity = new HttpEntity <String> (json_interface,httpHeaders);
580
            restTemplate.postForObject(uriComponents.toUri(),httpEntity,String.class);
581
            return repositoryInterface;
582

    
583
        } catch (JSONException e) {
584
            LOGGER.debug("Exception on addRepositoryInterface" , e);
585
            emailUtils.reportException(e);
586
            throw e;
587
        }
588
    }
589

    
590
    @Override
591
    public RepositoryInterface updateRepositoryInterface(@RequestParam("repoId") String repoId,
592
                                                         @RequestParam("registeredBy") String registeredBy,
593
                                                         @RequestBody RepositoryInterface repositoryInterface) throws Exception {
594

    
595
        this.updateBaseUrl(repoId,repositoryInterface.getId(),repositoryInterface.getBaseUrl());
596
        this.updateCompliance(repoId,repositoryInterface.getId(),repositoryInterface.getCompliance());
597
        this.updateValidationSet(repoId,repositoryInterface.getId(),repositoryInterface.getAccessSet());
598
        return repositoryInterface;
599
    }
600

    
601
    private void submitInterfaceValidation(Repository repo, String repoType, String userEmail, RepositoryInterface iFace) throws ValidatorServiceException {
602
        JobForValidation job = new JobForValidation();
603

    
604
        job.setActivationId(UUID.randomUUID().toString());
605
        job.setAdminEmails(Collections.singletonList(this.adminEmail));
606
        job.setBaseUrl(iFace.getBaseUrl());
607
        job.setDatasourceId(repo.getId());
608
        job.setDesiredCompatibilityLevel(iFace.getDesiredCompatibilityLevel());
609
        job.setInterfaceId(iFace.getId());
610
//        job.setInterfaceIdOld(null);
611
        job.setOfficialName(repo.getOfficialName());
612
        job.setRepoType(repoType);
613
        job.setUserEmail(userEmail);
614
        job.setValidationSet(iFace.getAccessSet());
615
        job.setRecords(-1);
616
        job.setRegistration(true);
617
        job.setUpdateExisting(false);
618

    
619
        this.validatorService.submitJobForValidation(job);
620
    }
621

    
622
    private RepositoryInterface createRepositoryInterface(Repository repo, RepositoryInterface iFace, String datatype) {
623

    
624
        iFace.setContentDescription("metadata");
625
        iFace.setCompliance("UNKNOWN");
626

    
627
        if (datatype.equals("re3data"))
628
            iFace.setAccessFormat("oai_datacite");
629
        else
630
            iFace.setAccessFormat("oai_dc");
631

    
632

    
633
        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
634
            iFace.setTypology(repo.getDatasourceClass());
635
        else if (datatype.equalsIgnoreCase("journal"))
636
            iFace.setTypology("pubsrepository::journal");
637
        else if (datatype.equalsIgnoreCase("aggregator"))
638
            iFace.setTypology("aggregator::pubsrepository::unknown");
639
        else if (datatype.equalsIgnoreCase("opendoar"))
640
            iFace.setTypology("pubsrepository::unknown");
641
        else if (datatype.equalsIgnoreCase("re3data"))
642
            iFace.setTypology("datarepository::unknown");
643

    
644
        iFace.setRemovable(true);
645
        iFace.setAccessProtocol("oai");
646
        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
647
        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
648
        if (iFace.getAccessSet().isEmpty()) {
649
            LOGGER.debug("set is empty: " + iFace.getAccessSet());
650
            iFace.removeAccessSet();
651
        }
652
        return iFace;
653
    }
654

    
655
    @Override
656
    public List<String> getDnetCountries() {
657
        LOGGER.debug("Getting dnet-countries!");
658
        return Converter.readFile("countries.txt");
659
    }
660

    
661
    @Override
662
    public List<String> getTypologies() {
663
        return Converter.readFile("typologies.txt");
664
    }
665

    
666
    @Override
667
    public List<Timezone> getTimezones() {
668
        List<String> timezones =  Converter.readFile("timezones.txt");
669
        return Converter.toTimezones(timezones);
670
    }
671

    
672
    @Override
673
    public List<String> getUrlsOfUserRepos(@PathVariable("user_email") String userEmail,
674
                                           @PathVariable("page") String page,
675
                                           @PathVariable("size") String size) throws JSONException {
676
        UriComponents uriComponents = UriComponentsBuilder
677
                .fromHttpUrl(baseAddress + "/api/baseurl/")
678
                .path("/{page}/{size}")
679
                .build().expand(page,size).encode();
680

    
681
        try{
682
            RequestFilter requestFilter = new RequestFilter();
683
            requestFilter.setRegisteredby(userEmail);
684
            return Arrays.asList(restTemplate.postForObject(uriComponents.toUri(),requestFilter, String[].class));
685
        }catch (Exception e){
686
            LOGGER.debug("Exception on addRepositoryInterface" , e);
687
            emailUtils.reportException(e);
688
            throw e;
689
        }
690
    }
691

    
692
    @Override
693
    public List<String> getDatasourceVocabularies(@PathVariable("mode") String mode) {
694

    
695
        List<String> resultSet = new ArrayList<>();
696
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
697
            if (mode.equalsIgnoreCase("aggregator")) {
698
                if (entry.getKey().contains("aggregator"))
699
                    resultSet.add(entry.getValue());
700
            } else if (mode.equalsIgnoreCase("journal")) {
701
                if (entry.getKey().contains("journal"))
702
                    resultSet.add(entry.getValue());
703
            } else if (mode.equalsIgnoreCase("opendoar")) {
704
                if (entry.getKey().contains("pubsrepository"))
705
                    resultSet.add(entry.getValue());
706
            } else if (mode.equalsIgnoreCase("re3data")) {
707
                if (entry.getKey().contains("datarepository"))
708
                    resultSet.add(entry.getValue());
709
            }
710
        }
711

    
712

    
713
        return resultSet;
714
    }
715

    
716
    private Vocabulary getVocabulary(String vocName) {
717

    
718
        if (!vocabularyMap.containsKey(vocName)) {
719
            vocabularyMap.put(vocName, vocabularyLoader.getVocabulary(vocName, Locale.ENGLISH, Locale.ROOT));
720
        }
721
        return vocabularyMap.get(vocName);
722
    }
723

    
724

    
725
    @Override
726
    public Map<String, String> getCompatibilityClasses(@PathVariable("mode") String mode)  {
727

    
728
        LOGGER.debug("Getting compatibility classes for mode: " + mode);
729
        Map<String, String> retMap = new HashMap<String, String>();
730

    
731
        Map<String, String> compatibilityClasses = this.getVocabulary("dnet:compatibilityLevel").getAsMap();
732
        boolean foundData = false;
733
        for (Map.Entry<String, String> entry : compatibilityClasses.entrySet()) {
734
            if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_ALL))
735
                return compatibilityClasses;
736
            else if (mode.equalsIgnoreCase(Constants.REPOSITORY_MODE_RE3DATA)) {
737
                if (entry.getKey().matches("^openaire[1-9].0_data$")) {
738
                    retMap.put(entry.getKey(), entry.getValue());
739
                    foundData = true;
740
                }
741
            } else {
742
                if (entry.getKey().matches("^openaire[1-9].0$") || entry.getKey().equals("driver"))
743
                    retMap.put(entry.getKey(), entry.getValue());
744
            }
745
        }
746

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

    
751
        return retMap;
752
    }
753

    
754
    @Override
755
    public Map<String, String> getDatasourceClasses(@PathVariable("mode") String mode)  {
756

    
757
        LOGGER.debug("Getting datasource classes for mode: " + mode);
758

    
759
        Map<String, String> retMap = new HashMap<String, String>();
760

    
761
        for (Map.Entry<String, String> entry : this.getVocabulary("dnet:datasource_typologies").getAsMap().entrySet()) {
762
            if (mode.equalsIgnoreCase("aggregator")) {
763
                if (entry.getKey().contains("aggregator"))
764
                    retMap.put(entry.getKey(), entry.getValue());
765
            } else if (mode.equalsIgnoreCase("journal")) {
766
                if (entry.getKey().contains("journal"))
767
                    retMap.put(entry.getKey(), entry.getValue());
768
            } else if (mode.equalsIgnoreCase("opendoar")) {
769
                if (entry.getKey().contains("pubsrepository"))
770
                    retMap.put(entry.getKey(), entry.getValue());
771
            } else if (mode.equalsIgnoreCase("re3data")) {
772
                if (entry.getKey().contains("datarepository"))
773
                    retMap.put(entry.getKey(), entry.getValue());
774
            }
775
        }
776
        return filterResults(retMap,mode);
777

    
778
    }
779

    
780
    private Map<String,String> filterResults(Map<String, String> map,String mode) {
781

    
782
        HashMap<String,String> filteredMap = new HashMap<>();
783
        for(String key:map.keySet())
784
            if(dataSourceClass.get(mode).contains(key))
785
                filteredMap.put(key,map.get(key));
786

    
787
        return filteredMap;
788
    }
789

    
790
    @Override
791
    public String getCountryName(String countryCode) {
792
        return inverseCountriesMap.get(countryCode);
793
    }
794

    
795
    @Override
796
    public MetricsInfo getMetricsInfoForRepository(@PathVariable("repoId")  String repoId) throws RepositoryServiceException {
797
        try {
798

    
799
            MetricsInfo metricsInfo = new MetricsInfo();
800
            metricsInfo.setDiagramsBaseURL(this.usageStatisticsDiagramsBaseURL);
801
            metricsInfo.setMetricsNumbers(getMetricsNumbers(getOpenAIREId(repoId)));
802
            return metricsInfo;
803

    
804
        } catch (Exception e) {
805
            LOGGER.error("Error while getting metrics info for repository: ", e);
806
            emailUtils.reportException(e);
807
            throw new RepositoryServiceException("General error", RepositoryServiceException.ErrorCode.GENERAL_ERROR);
808
        }
809
    }
810

    
811
    @Override
812
    public Map<String, String> getListLatestUpdate(@PathVariable("mode")  String mode) throws JSONException {
813
        if(mode.equals("opendoar"))
814
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(0).getLastCollectionDate());
815
        else
816
            /*
817
            * first api of re3data has null value on collection date
818
            * */
819
            return Collections.singletonMap("lastCollectionDate", getRepositoryInterface("openaire____::"+mode).get(1).getLastCollectionDate());
820
    }
821

    
822
    private void updateValidationSet(String repositoryId, String repositoryInterfaceId, String validationSet) throws Exception {
823
        UriComponents uriComponents = UriComponentsBuilder
824
                .fromHttpUrl(baseAddress + "/ds/api/oaiset")
825
                .queryParam("dsId",repositoryId)
826
                .queryParam("apiId",repositoryInterfaceId)
827
                .queryParam("oaiSet",validationSet)
828
                .build().encode();
829
       restTemplate.exchange(uriComponents.toUri(),HttpMethod.POST, null, ResponseEntity.class);
830

    
831
    }
832

    
833

    
834
    private void updateBaseUrl(String repositoryId, String repositoryInterfaceId, String baseUrl) {
835
        UriComponents uriComponents = UriComponentsBuilder
836
                .fromHttpUrl(baseAddress + "/ds/api/baseurl")
837
                .queryParam("dsId",repositoryId)
838
                .queryParam("apiId",repositoryInterfaceId)
839
                .queryParam("baseUrl",baseUrl)
840
                .build().encode();
841
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
842
    }
843

    
844
    private void updateCompliance(String repositoryId, String repositoryInterfaceId,String compliance) {
845
        UriComponents uriComponents = UriComponentsBuilder
846
                .fromHttpUrl(baseAddress + "/ds/api/compliance")
847
                .queryParam("dsId",repositoryId)
848
                .queryParam("apiId",repositoryInterfaceId)
849
                .queryParam("compliance",compliance)
850
                .build().encode();
851
        restTemplate.postForObject(uriComponents.toUri(),null,String.class);
852
    }
853

    
854
    private MetricsNumbers getMetricsNumbers(String openAIREID) throws BrokerException {
855

    
856
        //build the uri params
857
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usageStatisticsNumbersBaseURL + openAIREID + "/clicks");
858

    
859
        //create new template engine
860
        RestTemplate template = new RestTemplate();
861
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
862
        ResponseEntity<MetricsNumbers> resp;
863
        try {
864
            //communicate with endpoint
865
            resp = template.exchange(
866
                    builder.build().encode().toUri(),
867
                    HttpMethod.GET,
868
                    null,
869
                    new ParameterizedTypeReference<MetricsNumbers>() {
870
                    });
871
        } catch (RestClientException e) {
872
            LOGGER.debug("Exception on getMetricsNumbers" , e);
873
            emailUtils.reportException(e);
874
            throw e;
875
        }
876

    
877
        return resp.getBody();
878
    }
879

    
880
    private String getOpenAIREId(String repoId) {
881

    
882
        if (repoId != null && repoId.contains("::")) {
883
            return repoId.split("::")[0] + "::" + DigestUtils.md5Hex(repoId.split("::")[1]);
884
        }
885

    
886
        return null;
887
    }
888

    
889
    private UriComponents searchDatasource(String page,String size){
890

    
891
        return UriComponentsBuilder
892
                .fromHttpUrl(baseAddress + "/ds/search/")
893
                .path("/{page}/{size}/")
894
                .queryParam("requestSortBy","officialname")
895
                .queryParam("order","ASCENDING")
896
                .build().expand(page, size).encode();
897
    }
898

    
899
    private UriComponents searchSnipperDatasource(String page,String size){
900

    
901
        return UriComponentsBuilder
902
                .fromHttpUrl(baseAddress + "/ds/searchsnippet/")
903
                .path("/{page}/{size}/")
904
                .queryParam("requestSortBy","officialname")
905
                .queryParam("order","ASCENDING")
906
                .build().expand(page, size).encode();
907
    }
908

    
909
    private UriComponents searchRegisteredDatasource(String requestSortBy, String order, String page,String size){
910

    
911
        return UriComponentsBuilder
912
                .fromHttpUrl(baseAddress + "/ds/searchregistered/")
913
                .path("/{page}/{size}/")
914
                .queryParam("requestSortBy",requestSortBy)
915
                .queryParam("order",order)
916
                .build().expand(page, size).encode();
917
    }
918

    
919
    private String getRepositoryType(String typology){
920
        return invertedDataSourceClass.get(typology);
921
    }
922

    
923

    
924
}
(12-12/20)