Project

General

Profile

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

    
3
import com.fasterxml.jackson.databind.JsonNode;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import eu.dnetlib.domain.data.Repository;
6
import eu.dnetlib.repo.manager.shared.BrokerException;
7
import eu.dnetlib.repo.manager.shared.Term;
8
import eu.dnetlib.repo.manager.shared.Tuple;
9
import eu.dnetlib.repo.manager.shared.broker.*;
10
import io.swagger.annotations.ApiParam;
11
import org.json.JSONException;
12
import org.springframework.beans.factory.annotation.Autowired;
13
import org.springframework.beans.factory.annotation.Value;
14
import org.springframework.core.ParameterizedTypeReference;
15
import org.springframework.http.*;
16
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
17
import org.springframework.security.access.prepost.PreAuthorize;
18
import org.springframework.stereotype.Component;
19
import org.springframework.util.LinkedMultiValueMap;
20
import org.springframework.util.MultiValueMap;
21
import org.springframework.web.bind.annotation.PathVariable;
22
import org.springframework.web.bind.annotation.RequestBody;
23
import org.springframework.web.bind.annotation.RequestParam;
24
import org.springframework.web.client.RestClientException;
25
import org.springframework.web.client.RestTemplate;
26
import org.springframework.web.util.UriComponents;
27
import org.springframework.web.util.UriComponentsBuilder;
28

    
29
import javax.annotation.PostConstruct;
30
import java.io.IOException;
31
import java.io.InputStream;
32
import java.net.URL;
33
import java.util.*;
34

    
35
@Component
36
public class BrokerApiImpl implements BrokerApi {
37

    
38
    @Autowired
39
    private RepositoryApiImpl repoAPI;
40
    @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}${services.broker.openaire}")
41
    private String openairePath;
42
    @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}")
43
    private String apiPath;
44
    @Value("${topic_types.url}")
45
    private String topicsURL;
46

    
47
    private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
48
            .getLogger(BrokerApiImpl.class);
49

    
50
    private RestTemplate restTemplate = null;
51

    
52
    private HttpHeaders httpHeaders;
53

    
54
    private HashMap<String,Term> topics = new HashMap<String, Term>();
55

    
56
    @Autowired
57
    private EmailUtils emailUtils;
58

    
59
    @PostConstruct
60
    private void initDnetTopicsMap() {
61

    
62
        restTemplate = new RestTemplate();
63
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
64

    
65
        httpHeaders = new HttpHeaders();
66
        httpHeaders.set("Content-Type", "application/json");
67

    
68
        LOGGER.debug("Init dnet topics!");
69
        InputStream is = null;
70
        try {
71
            is = new URL(topicsURL).openStream();
72
            ObjectMapper mapper = new ObjectMapper();
73
            JsonNode root = mapper.readTree(is);
74
            for (JsonNode term : root.path("terms") )
75
                topics.put(term.path("code").textValue(), parseTerm(term));
76
        } catch (IOException e) {
77
            LOGGER.debug("Exception on initDnetTopicsMap" , e);
78
            emailUtils.reportException(e);
79
        }
80
    }
81

    
82
    private Term parseTerm(JsonNode term) {
83
        return new Term(term.path("englishName").textValue(),term.path("nativeName").textValue(),
84
                term.path("encoding").textValue(),term.path("code").textValue());
85
    }
86

    
87

    
88
    @Override
89
    @PreAuthorize("hasRole('ROLE_USER')")
90
    public DatasourcesBroker getDatasourcesOfUser(@RequestParam("user")
91
                                                    @ApiParam(value = "User email", required = true) String user,
92
                                                  @RequestParam("includeShared")
93
                                                    @ApiParam(value = "Include shared datasources", required = true , defaultValue = "false") String includeShared,
94
                                                  @RequestParam("includeByOthers")
95
                                                    @ApiParam(value = "Include datasources of other", required = true,defaultValue = "false") String includeByOthers) throws JSONException {
96

    
97
        DatasourcesBroker ret = new DatasourcesBroker();
98
        try {
99
            ret.setDatasourcesOfUser(getDatasourcesOfUserType(getRepositoriesOfUser(user)));
100
            //TODO fix bug when values are true
101
            if (Boolean.parseBoolean(includeShared)) {
102
                List<String> sharedDatasourceIds = new ArrayList<String>();
103
                ret.setSharedDatasources(getDatasourcesOfUserType(getRepositoriesByIds(sharedDatasourceIds)));
104
            }
105

    
106
            if (Boolean.parseBoolean(includeByOthers)) {
107
                ret.setDatasourcesOfOthers(getDatasourcesOfUserType(getRepositoriesOfUser(user)));
108
            }
109
        } catch (BrokerException e) {
110
            LOGGER.debug("Exception on getDatasourcesOfUser" , e);
111
            emailUtils.reportException(e);
112
        }
113

    
114
        return ret;
115
    }
116

    
117
    @Override
118
    public List<BrowseEntry> getTopicsForDatasource(@PathVariable("datasourceName")  String datasourceName) throws BrokerException {
119
        final String service = "/topicsForDatasource";
120

    
121
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
122
                .queryParam("ds", datasourceName);
123

    
124
        ResponseEntity<List<BrowseEntry>> resp;
125
        try {
126
            resp = restTemplate.exchange(
127
                    builder.build().encode().toUri(),
128
                    HttpMethod.GET,
129
                    null,
130
                    new ParameterizedTypeReference<List<BrowseEntry>>() {
131
                    });
132
        } catch (RestClientException e) {
133
            LOGGER.debug("Exception on getTopicsForDatasource" , e);
134
            emailUtils.reportException(e);
135
            throw new BrokerException(e);
136
        }
137

    
138
        return resp.getBody();
139
    }
140

    
141
    @Override
142
    @PreAuthorize("hasRole('ROLE_USER')")
143
    public EventsPage advancedShowEvents(@PathVariable("page") String page,
144
                                         @PathVariable("size") String size,
145
                                         @RequestBody AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException {
146

    
147
        final String service = "/events/{page}/{pageSize}";
148

    
149
        Map<String, Long> uriParams = new HashMap<>();
150
        uriParams.put("page", Long.parseLong(page));
151
        uriParams.put("pageSize", Long.parseLong(size));
152

    
153
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service);
154

    
155
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
156
        advQueryObject.setPage(Long.parseLong(page));
157
        HttpEntity<AdvQueryObject> entity = new HttpEntity<>(advQueryObject, httpHeaders);
158
        ResponseEntity<EventsPage> resp;
159
        try {
160
            resp = restTemplate.exchange(
161
                    builder.buildAndExpand(uriParams).encode().toUri(),
162
                    HttpMethod.POST,
163
                    entity,
164
                    new ParameterizedTypeReference<EventsPage>() {
165
                    }
166
            );
167
        } catch (RestClientException e) {
168
            LOGGER.debug("Exception on advancedShowEvents" , e);
169
            emailUtils.reportException(e);
170
            throw new BrokerException(e);
171
        }
172
        return resp.getBody();
173

    
174

    
175
    }
176

    
177

    
178
    private List<Tuple<BrowseEntry, String>> getDatasourcesOfUserType(List<Repository> repositories) throws BrokerException {
179

    
180
        List<Tuple<BrowseEntry, String>> entries = new ArrayList<>();
181
        for (Repository repo : repositories) {
182
            BrowseEntry temp = new BrowseEntry();
183
            temp.setValue(repo.getOfficialName());
184
            temp.setSize(new Long(0));
185
            for (BrowseEntry e : getTopicsForDatasource(repo.getOfficialName())) {
186
                temp.setSize(temp.getSize() + e.getSize());
187
            }
188
            Tuple<BrowseEntry, String> tup = new Tuple<>(temp, repo.getLogoUrl());
189
            entries.add(tup);
190
        }
191

    
192
        // sort the collection by the second field of the tuple which is size
193
        Collections.sort(entries, new Comparator<Tuple<BrowseEntry, String>>() {
194
            @Override
195
            public int compare(Tuple<BrowseEntry, String> e1, Tuple<BrowseEntry, String> e2) {
196
                return (int) (e2.getFirst().getSize().longValue() - e1.getFirst().getSize().longValue());
197
            }
198
        });
199

    
200
        return entries;
201
    }
202

    
203

    
204

    
205
    private List<Repository> getRepositoriesOfUser(String userEmail) throws JSONException {
206

    
207
        int page = 0;
208
        int size = 50;
209
        List<Repository> rs ;
210
        List<Repository> resultSet = new ArrayList<>();
211

    
212
        while (true){
213
            rs = repoAPI.getRepositoriesOfUser(userEmail, String.valueOf(page), String.valueOf(size));
214
            resultSet.addAll(rs);
215
            page+=1;
216
            if(rs.size() == 0) break;
217
        }
218
        return resultSet;
219
    }
220

    
221
    private List<Repository> getRepositoriesByIds(List<String> sharedDatasourceIds) {
222
        return null;
223
    }
224

    
225
    @Override
226
    @PreAuthorize("hasRole('ROLE_USER')")
227
    public EventsPage showEvents(@RequestParam("datasourceName") String datasourceName,
228
                                 @RequestParam("topic") String topic,
229
                                 @RequestParam("page") String page,
230
                                 @RequestParam("size") String size) throws BrokerException, JSONException {
231

    
232
        final String service = "/events";
233

    
234
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
235
                .queryParam("ds", datasourceName)
236
                .queryParam("topic", topic)
237
                .path("/{page}/{size}/");
238

    
239
        ResponseEntity<EventsPage> resp;
240
        try {
241
            resp = restTemplate.exchange(
242
                    builder.build().expand(page, size).encode().toUri(),
243
                    HttpMethod.GET,
244
                    null,
245
                    new ParameterizedTypeReference<EventsPage>() {
246
                    });
247
        } catch (RestClientException e) {
248
            LOGGER.debug("Exception on showEvents" , e);
249
            emailUtils.reportException(e);
250
            throw new BrokerException(e);
251
        }
252
        return resp.getBody();
253
    }
254

    
255
    @Override
256
    @PreAuthorize("hasRole('ROLE_USER')")
257
    public Map<String, List<SimpleSubscriptionDesc>> getSimpleSubscriptionsOfUser(@PathVariable("userEmail")  String userEmail)
258
            throws BrokerException {
259

    
260
        final String service = "/subscriptions";
261

    
262
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service)
263
                .queryParam("email", userEmail);
264

    
265
        LOGGER.debug(builder.build().encode().toUri());
266
        ResponseEntity<Map<String, List<SimpleSubscriptionDesc>>> resp;
267
        try {
268
            resp = restTemplate.exchange(
269
                    builder.build().encode().toUri(),
270
                    HttpMethod.GET,
271
                    null,
272
                    new ParameterizedTypeReference<Map<String, List<SimpleSubscriptionDesc>>>() {
273
                    });
274
        } catch (RestClientException e) {
275
            LOGGER.debug("Exception on getSimpleSubscriptionsOfUser" , e);
276
            emailUtils.reportException(e);
277
            throw new BrokerException(e);
278
        }
279
        return resp.getBody();
280
    }
281

    
282
    @Override
283
    @PreAuthorize("hasRole('ROLE_USER') ")
284
    public Subscription subscribe(@RequestBody  OpenaireSubscription obj) throws BrokerException {
285
        final String service = "/subscribe";
286

    
287
        //build the uri params
288
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service);
289

    
290
        HttpEntity<OpenaireSubscription> entity = new HttpEntity<>(obj, httpHeaders);
291

    
292
        //create new template engine
293
        RestTemplate template = new RestTemplate();
294
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
295
        ResponseEntity<Subscription> resp;
296
        try {
297
            //communicate with endpoint
298
            resp = restTemplate.exchange(
299
                    builder.build().encode().toUri(),
300
                    HttpMethod.POST,
301
                    entity,
302
                    new ParameterizedTypeReference<Subscription>() {
303
                    });
304
        } catch (RestClientException e) {
305
            LOGGER.debug("Exception on OpenaireSubscription" , e);
306
            emailUtils.reportException(e);
307
            throw new BrokerException(e);
308
        }
309

    
310
        return resp.getBody();
311
    }
312

    
313
    @Override
314
    @PreAuthorize("hasRole('ROLE_USER')")
315
    public ResponseEntity<Object> unsubscribe(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException {
316
        final String service = "/subscriptions/" + subscriptionId;
317

    
318
        //build the uri params
319
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service);
320

    
321
        try {
322
            //communicate with endpoint
323
            restTemplate.exchange(
324
                    builder.build().encode().toUri(),
325
                    HttpMethod.DELETE,
326
                    null,
327
                    new ParameterizedTypeReference<Void>() {
328
                    });
329
        } catch (RestClientException e) {
330
            LOGGER.debug("Exception on unsubscribe" , e);
331
            emailUtils.reportException(e);
332
            throw new BrokerException(e);
333
        }
334
        return new ResponseEntity<>("OK",HttpStatus.OK);
335
    }
336

    
337
    @Override
338
    @PreAuthorize("hasRole('ROLE_USER')")
339
    public Subscription getSubscription(@PathVariable("subscriptionId") String subscriptionId) throws BrokerException {
340
        final String service = "/subscriptions/" + subscriptionId;
341

    
342
        //build the uri params
343
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service);
344

    
345
        ResponseEntity<Subscription> resp;
346
        try {
347
            //communicate with endpoint
348
            resp = restTemplate.exchange(
349
                    builder.build().encode().toUri(),
350
                    HttpMethod.GET,
351
                    null,
352
                    new ParameterizedTypeReference<Subscription>() {
353
                    });
354
        } catch (RestClientException e) {
355
            LOGGER.debug("Exception on getSubscription" , e);
356
            emailUtils.reportException(e);
357
            throw new BrokerException(e);
358
        }
359
        return resp.getBody();
360
    }
361

    
362
    @Override
363
    public Map<String, Term> getDnetTopics() throws BrokerException {
364
        return topics;
365
    }
366

    
367
    @Override
368
    @PreAuthorize("hasRole('ROLE_USER')")
369
    public EventsPage getNotificationsBySubscriptionId(@PathVariable("subscriptionId") String subscriptionId,
370
                                                       @PathVariable("page") String page,
371
                                                       @PathVariable("size") String size
372
                                                       ) throws BrokerException {
373

    
374
        UriComponents uriComponents = UriComponentsBuilder
375
                .fromHttpUrl(openairePath + "/notifications/")
376
                .path("/{id}/{page}/{size}/")
377
                .build().expand(subscriptionId,page, size).encode();
378

    
379
        ResponseEntity<EventsPage> resp;
380
        try {
381
            resp = restTemplate.exchange(
382
                    uriComponents.toUri(),
383
                    HttpMethod.GET,
384
                    null,
385
                    new ParameterizedTypeReference<EventsPage>() {
386
                    });
387
        } catch (RestClientException e) {
388
            LOGGER.debug("Exception on getNotificationsBySubscriptionId" , e);
389
            emailUtils.reportException(e);
390
            throw new BrokerException(e);
391
        }
392
        return resp.getBody();
393
    }
394

    
395
    //@Override
396
    public Map<String, List<Subscription>> getSubscriptionsOfUser(/*@PathVariable("userEmail")*/ String userEmail)
397
            throws BrokerException {
398

    
399
        Map<String, List<SimpleSubscriptionDesc>> simpleSubs = getSimpleSubscriptionsOfUser(userEmail);
400
        Map<String,List<Subscription>> subs = new HashMap<>();
401
        List<Subscription> subscriptions = null;
402

    
403
        for(String s:simpleSubs.keySet()){
404
            List<SimpleSubscriptionDesc> simpleSubscriptionDescs = simpleSubs.get(s);
405
            for(SimpleSubscriptionDesc simpleSubscriptionDesc : simpleSubscriptionDescs) {
406
                subscriptions = new ArrayList<>();
407
                subscriptions.add(getSubscription(simpleSubscriptionDesc.getId()));
408
            }
409
            subs.put(s,subscriptions);
410
        }
411
        return subs;
412
    }
413

    
414

    
415
}
(2-2/15)