package eu.dnetlib.repo.manager.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.dnetlib.domain.data.Repository; import eu.dnetlib.repo.manager.shared.BrokerException; import eu.dnetlib.repo.manager.shared.Term; import eu.dnetlib.repo.manager.shared.Tuple; import eu.dnetlib.repo.manager.shared.broker.*; import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import javax.annotation.PostConstruct; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.*; @Service("brokerService") public class BrokerServiceImpl implements BrokerService { @Autowired private RepositoryServiceImpl repoAPI; @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}${services.broker.openaire}") private String openairePath; @Value("${services.broker.url}:${services.broker.port}/${services.broker.api}") private String apiPath; @Value("${topic_types.url}") private String topicsURL; private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger .getLogger(BrokerServiceImpl.class); @Autowired RestTemplate restTemplate ; private HttpHeaders httpHeaders; private HashMap topics = new HashMap(); @Autowired private EmailUtils emailUtils; @PostConstruct private void initDnetTopicsMap() { httpHeaders = new HttpHeaders(); httpHeaders.set("Content-Type", "application/json"); LOGGER.debug("Init dnet topics!"); InputStream is = null; try { is = new URL(topicsURL).openStream(); ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(is); for (JsonNode term : root.path("terms") ) topics.put(term.path("code").textValue(), parseTerm(term)); } catch (IOException e) { LOGGER.debug("Exception on initDnetTopicsMap" , e); emailUtils.reportException(e); } } private Term parseTerm(JsonNode term) { return new Term(term.path("englishName").textValue(),term.path("nativeName").textValue(), term.path("encoding").textValue(),term.path("code").textValue()); } @Override public DatasourcesBroker getDatasourcesOfUser(String user,String includeShared,String includeByOthers) throws JSONException { DatasourcesBroker ret = new DatasourcesBroker(); try { ret.setDatasourcesOfUser(getDatasourcesOfUserType(getRepositoriesOfUser(user))); //TODO fix bug when values are true if (Boolean.parseBoolean(includeShared)) { List sharedDatasourceIds = new ArrayList(); ret.setSharedDatasources(getDatasourcesOfUserType(getRepositoriesByIds(sharedDatasourceIds))); } if (Boolean.parseBoolean(includeByOthers)) { ret.setDatasourcesOfOthers(getDatasourcesOfUserType(getRepositoriesOfUser(user))); } } catch (BrokerException e) { LOGGER.debug("Exception on getDatasourcesOfUser" , e); emailUtils.reportException(e); } return ret; } @Override public List getTopicsForDatasource(String datasourceName) throws BrokerException { final String service = "/topicsForDatasource"; UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service) .queryParam("ds", datasourceName); ResponseEntity> resp; try { resp = restTemplate.exchange( builder.build().encode().toUri(), HttpMethod.GET, null, new ParameterizedTypeReference>() { }); } catch (RestClientException e) { LOGGER.debug("Exception on getTopicsForDatasource" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } @Override public EventsPage advancedShowEvents(String page, String size, AdvQueryObject advQueryObject) throws BrokerException, JSONException ,IOException { final String service = "/events/{page}/{pageSize}"; Map uriParams = new HashMap<>(); uriParams.put("page", Long.parseLong(page)); uriParams.put("pageSize", Long.parseLong(size)); UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service); MultiValueMap headers = new LinkedMultiValueMap<>(); advQueryObject.setPage(Long.parseLong(page)); HttpEntity entity = new HttpEntity<>(advQueryObject, httpHeaders); ResponseEntity resp; try { resp = restTemplate.exchange( builder.buildAndExpand(uriParams).encode().toUri(), HttpMethod.POST, entity, new ParameterizedTypeReference() { } ); } catch (RestClientException e) { LOGGER.debug("Exception on advancedShowEvents" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } private List> getDatasourcesOfUserType(List repositories) throws BrokerException { List> entries = new ArrayList<>(); for (Repository repo : repositories) { BrowseEntry temp = new BrowseEntry(); temp.setValue(repo.getOfficialName()); temp.setSize(new Long(0)); for (BrowseEntry e : getTopicsForDatasource(repo.getOfficialName())) { temp.setSize(temp.getSize() + e.getSize()); } Tuple tup = new Tuple<>(temp, repo.getLogoUrl()); entries.add(tup); } // sort the collection by the second field of the tuple which is size Collections.sort(entries, new Comparator>() { @Override public int compare(Tuple e1, Tuple e2) { return (int) (e2.getFirst().getSize().longValue() - e1.getFirst().getSize().longValue()); } }); return entries; } private List getRepositoriesOfUser(String userEmail) throws JSONException { int page = 0; int size = 50; List rs ; List resultSet = new ArrayList<>(); while (true){ rs = repoAPI.getRepositoriesOfUser(userEmail, String.valueOf(page), String.valueOf(size)); resultSet.addAll(rs); page+=1; if(rs.size() == 0) break; } return resultSet; } private List getRepositoriesByIds(List sharedDatasourceIds) { return null; } @Override public EventsPage showEvents(String datasourceName, String topic, String page, String size) throws BrokerException, JSONException { final String service = "/events"; UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service) .queryParam("ds", datasourceName) .queryParam("topic", topic) .path("/{page}/{size}/"); ResponseEntity resp; try { resp = restTemplate.exchange( builder.build().expand(page, size).encode().toUri(), HttpMethod.GET, null, new ParameterizedTypeReference() { }); } catch (RestClientException e) { LOGGER.debug("Exception on showEvents" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } @Override public Map> getSimpleSubscriptionsOfUser(String userEmail) throws BrokerException { final String service = "/subscriptions"; UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service) .queryParam("email", userEmail); LOGGER.debug(builder.build().encode().toUri()); ResponseEntity>> resp; try { resp = restTemplate.exchange( builder.build().encode().toUri(), HttpMethod.GET, null, new ParameterizedTypeReference>>() { }); } catch (RestClientException e) { LOGGER.debug("Exception on getSimpleSubscriptionsOfUser" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } @Override public Subscription subscribe(OpenaireSubscription obj) throws BrokerException { final String service = "/subscribe"; //build the uri params UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openairePath + service); HttpEntity entity = new HttpEntity<>(obj, httpHeaders); //create new template engine RestTemplate template = new RestTemplate(); template.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); ResponseEntity resp; try { //communicate with endpoint resp = restTemplate.exchange( builder.build().encode().toUri(), HttpMethod.POST, entity, new ParameterizedTypeReference() { }); } catch (RestClientException e) { LOGGER.debug("Exception on OpenaireSubscription" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } @Override public ResponseEntity unsubscribe(String subscriptionId) throws BrokerException { final String service = "/subscriptions/" + subscriptionId; //build the uri params UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service); try { //communicate with endpoint restTemplate.exchange( builder.build().encode().toUri(), HttpMethod.DELETE, null, new ParameterizedTypeReference() { }); } catch (RestClientException e) { LOGGER.debug("Exception on unsubscribe" , e); emailUtils.reportException(e); throw new BrokerException(e); } return new ResponseEntity<>("OK",HttpStatus.OK); } @Override public Subscription getSubscription( String subscriptionId) throws BrokerException { final String service = "/subscriptions/" + subscriptionId; //build the uri params UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiPath + service); ResponseEntity resp; try { //communicate with endpoint resp = restTemplate.exchange( builder.build().encode().toUri(), HttpMethod.GET, null, new ParameterizedTypeReference() { }); } catch (RestClientException e) { LOGGER.debug("Exception on getSubscription" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } @Override public Map getDnetTopics() throws BrokerException { return topics; } @Override public EventsPage getNotificationsBySubscriptionId(String subscriptionId, String page, String size) throws BrokerException { UriComponents uriComponents = UriComponentsBuilder .fromHttpUrl(openairePath + "/notifications/") .path("/{id}/{page}/{size}/") .build().expand(subscriptionId,page, size).encode(); ResponseEntity resp; try { resp = restTemplate.exchange( uriComponents.toUri(), HttpMethod.GET, null, new ParameterizedTypeReference() { }); } catch (RestClientException e) { LOGGER.debug("Exception on getNotificationsBySubscriptionId" , e); emailUtils.reportException(e); throw new BrokerException(e); } return resp.getBody(); } //@Override public Map> getSubscriptionsOfUser(String userEmail) throws BrokerException { Map> simpleSubs = getSimpleSubscriptionsOfUser(userEmail); Map> subs = new HashMap<>(); List subscriptions = null; for(String s:simpleSubs.keySet()){ List simpleSubscriptionDescs = simpleSubs.get(s); for(SimpleSubscriptionDesc simpleSubscriptionDesc : simpleSubscriptionDescs) { subscriptions = new ArrayList<>(); subscriptions.add(getSubscription(simpleSubscriptionDesc.getId())); } subs.put(s,subscriptions); } return subs; } }